Laravel 事件與監聽器

下面是一個完整的用戶注冊事件和監聽器的實現示例,包含事件、監聽器、注冊、觸發等完整流程。

一、軟件版本

  • php: 8.2.20
  • laravel: 11
  • mysql: 8.0.29

二、完整實現過程

1.創建事件

1.1 首先創建用戶注冊事件

php artisan make:event UserRegistered

1.2 編輯app/Events/UserRegistered.php

<?php
namespace App\Events;use App\Models\User;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;class UserRegistered
{use Dispatchable, InteractsWithSockets, SerializesModels;/*** 創建一個新的事件實例*/public function __construct(public User $user){}
}

2. 創建監聽器

2.1 創建兩個監聽器:發送歡迎郵件記錄注冊日志

php artisan make:listener SendWelcomeEmail --event=UserRegistered
php artisan make:listener LogUserRegistration --event=UserRegistered

2.2 編輯 app/Listeners/SendWelcomeEmail.php

<?phpnamespace App\Listeners;use App\Events\UserRegistered;
use App\Mail\WelcomeEmail;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Mail;class SendWelcomeEmail implements ShouldQueue
{/*** 處理事件** @param UserRegistered $event* @return void*/public function handle(UserRegistered $event){Mail::to($event->user->email)->send(new WelcomeEmail($event->user));}/*** 處理失敗的任務** @param UserRegistered $event* @param \Throwable $exception* @return void*/public function failed(UserRegistered $event, $exception){// 發送失敗通知給管理員}
}

2.3 編輯 app/Listeners/LogUserRegistration.php

<?phpnamespace App\Listeners;use App\Events\UserRegistered;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;class LogUserRegistration
{/*** Create the event listener.*/public function __construct(){//}/*** Handle the event.*/public function handle(UserRegistered $event): void{Log::info('新用戶注冊完成: '.$event->user->email);}
}

3. 注冊事件和監聽器

3.1 創建 app/Providers/EventServiceProvider.php

php artisan make:provider EventServiceProvider

3.2 編輯 app/Providers/EventServiceProvider.php

<?phpnamespace App\Providers;use App\Events\UserRegistered;
use App\Listeners\LogUserRegistration;
use App\Listeners\SendWelcomeEmail;
use Illuminate\Support\ServiceProvider;class EventServiceProvider extends ServiceProvider
{/*** 事件與監聽器的映射關系*/protected $listen = [UserRegistered::class => [SendWelcomeEmail::class,LogUserRegistration::class],];/*** Register services.*/public function register(): void{//}/*** Bootstrap services.* 注冊任何其他事件*/public function boot(): void{//}
}

4. 創建郵件類

4.1 創建歡迎郵件模板

php artisan make:mail WelcomeEmail --markdown=emails.welcome

4.2 編輯 app/Mail/WelcomeEmail.php

<?phpnamespace App\Mail;use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;class WelcomeEmail extends Mailable
{use Queueable, SerializesModels;/*** 創建一個新的消息實例** @param User $user*/public function __construct(public User $user){}/*** 構建消息** @return $this*/public function build(){return $this->markdown('emails.welcome')->subject('歡迎加入我們的平臺');}
}

4.2 編輯 resources/views/emails/welcome.blade.php

@component('mail::message')# 歡迎, {{ $user->name }}!感謝您注冊我們的平臺。您的賬戶已經成功創建。@component('mail::button', ['url' => url('/dashboard')])訪問儀表盤@endcomponent謝謝,{{ config('app.name') }}
@endcomponent

4.3 郵件配置 .env

MAIL_MAILER=smtp
MAIL_SCHEME=null
MAIL_HOST=smtp.163.com
MAIL_PORT=465
MAIL_ENCRYPTION=ssl
MAIL_USERNAME=xxx@163.com
MAIL_PASSWORD=GTkCEsxxxxxxx
MAIL_FROM_ADDRESS="xxxx@163.com"
MAIL_FROM_NAME="${APP_NAME}"

5. 測試事件

5.1 創建測試

php artisan make:test UserRegistrationTest

5.2 編輯 tests/Feature/UserRegistrationTest.php

<?phpnamespace Tests\Feature;use App\Events\UserRegistered;
use App\Mail\WelcomeEmail;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Mail;
use Tests\TestCase;class UserRegistrationTest extends TestCase
{use RefreshDatabase;public function test_user_registration_dispatches_event(){Event::fake();$user = User::factory()->create();event(new UserRegistered($user));Event::assertDispatched(UserRegistered::class, function ($event) use ($user) {return $event->user->id === $user->id;});}public function test_welcome_email_is_sent(){Mail::fake();$user = User::factory()->create();event(new UserRegistered($user));Mail::assertSent(WelcomeEmail::class, function ($mail) use ($user) {return $mail->user->id === $user->id;});}
}

5.3 測試結果

在這里插入圖片描述

6. 在控制器中觸發事件

6.1 編輯 app/Http/Controllers/Auth/RegisterController.php

<?phpnamespace App\Http\Controllers\Auth;use App\Events\UserRegistered;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Hash;class RegisterController extends Controller
{public function register(){// 驗證邏輯...$user = User::create(['name' => request('name'),'email' => request('email'),'password' => Hash::make(request('password')),]);// 觸發用戶注冊事件event(new UserRegistered($user));// 或者使用靜態方法// UserRegistered::dispatch($user);return redirect('/home')->with('success', '注冊成功!');}
}

7. 訪問控制器后

7.1 laravel日志中顯示

在這里插入圖片描述

7.2 目標郵箱收到郵件

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93754.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93754.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93754.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端 React 實現數據懶加載-滾動觸底加載數據

在 React 中使用 Intersection Observer API 實現觸底加載分頁&#xff08;無限滾動&#xff09;1.基本實現思路 在列表底部放置一個 哨兵元素&#xff08;Sentinel&#xff09;&#xff08;如 <div>&#xff09;。使用 IntersectionObserver 監聽該元素是否進入視口&…

MySQL 50 道經典練習題及答案

目錄 一、數據表設計與初始化 1. 數據表結構說明 2. 建表語句 3. 插入測試數據 二、練習題及答案 1. 查詢 "01" 課程比 "02" 課程成績高的學生的信息及課程分數 2. 查詢同時存在 "01" 課程和 "02" 課程的情況 3. 查詢存在 &qu…

電競護航小程序搭建三角洲俱樂部護航派單小程序開發游戲派單系統定制開發

成品系統&#xff0c;可以快速搭建。功能概述&#xff1a;商家入駐、老板點單、快捷發單、自定義發單、發單列表、管事入駐、訂單審核裁決、打手入駐、打手排行榜、邀請排行榜、賬戶充值、余額提現、成為客服等

MYSQL-增刪查改CRUD

目錄 &#x1f33f;前言&#xff1a; &#x1f33f;增-C-Create-新增 &#x1f9ca;單行數據全列插入 &#x1f34b;?&#x1f7e9;語法&#xff1a; &#x1f34b;?&#x1f7e9;演示&#xff1a; &#x1f9ca;指定列插入 &#x1f34b;?&#x1f7e9;語法&#xf…

【Loss學習筆記】Focal loss、QFL、DFL、VFL——目標檢測定位損失函數詳解

文章目錄Focal loss&#xff08;2018 ICCV &#xff0c;RetinaNet&#xff09;1、Focal Loss 提出背景問題一&#xff1a;正負樣本數量不均衡問題問題二&#xff1a;難分類/易分類樣本數量不均衡問題對兩個問題的解決2、正負樣本數量不均衡問題的解決&#xff1a;Focal loss 的…

nertctl使用了解

測試了幾個容器&#xff0c;似乎未對k8s的containerd產生影響&#xff0c;都能訪問 再次測試&#xff0c;containerd發生了重啟&#xff0c;nrtdctl啟動的容器都沒了 #### sealos 創建containerd集群 sealos run registry.cn-shanghai.aliyuncs.com/labring/kubernetes:v1.29…

三、k8s 1.29 之 資源清單

一、什么是資源 資源(Resources) 是指集群中可被分配、管理和調度的各種實體,既包括計算、存儲、網絡等基礎設施資源,也包括 K8s 自身定義的 API 對象(如 Pod、Deployment 等)。這些資源是 K8s 調度和管理工作負載的核心基礎。 Kubernetes 中的資源本質上是 “可被操作的…

React中常用的Hook(useEffect、useRef、useMemo、useNavigate、useParams)

React hook1&#xff1a;useEffect 在編程中&#xff0c;副作用是指函數或表達式在執行過程中對外部環境產生影響的行為。例如&#xff1a; 修改外部變量&#xff08;如全局變量、DOM、API 請求、設置定時器等&#xff09; 什么是純函數&#xff1f; // 純函數&#xff1a;輸入…

關聯規則挖掘1:Apriori算法

目錄 一、Apriori算法核心原理 1. 基本概念 2. Apriori性質 二、完整案例計算&#xff08;超市購物數據&#xff09; ?步驟1&#xff1a;按字母序重排每筆交易? ?步驟2&#xff1a;統計頻繁1-項集&#xff08;min_support40%&#xff09;?? ?步驟3&#xff1a;生成…

基于 C++ 線程池的多線程目標檢測后處理系統設計與實現

在實際的智能視頻分析系統中,目標檢測(如 YOLOv5)只是第一步。檢測結果往往需要進行后續處理:畫框、報警、推流、日志記錄等。這些操作如果在檢測主線程中同步執行,會嚴重拖慢整體推理速度。 本文將帶你從零實現一個基于 C++ 模板線程池的異步后處理系統,實現“檢測與后…

Java并發容器詳解

1. JUC并發容器概述 Java集合容器框架主要有四大類別&#xff1a;List、Set、Queue、Map。常見的ArrayList、LinkedList、HashMap等容器都是非線程安全的。 Java提供了同步容器&#xff08;如Vector、Hashtable、SynchronizedList&#xff09;通過synchronized實現同步&#xf…

SpringAI系列---【SpringA集成OllamaI如何先調用向量庫,再把查到的結果一起傳給大模型?】

SpringAI如何先調用向量庫&#xff0c;再把查到的結果一起傳給大模型&#xff1f; 1.引入pom <dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-ollama</artifactId></depend…

告別“測試滯后”:AI實時測試工具在敏捷開發中的落地經驗

告別“測試滯后”&#xff1a;AI實時測試工具在敏捷開發中的落地經驗 在敏捷開發的“快速迭代”節奏中&#xff0c;測試環節常常成為“拖后腿”的短板。某互聯網公司的敏捷團隊曾陷入這樣的循環&#xff1a;2周迭代周期中&#xff0c;開發用10天完成功能&#xff0c;留給測試的…

K8S-Pod資源對象

一、K8S架構與組件1、K8S架構k8s 總體架構采用了經典的 maste/slave 架構模式&#xff0c;分 master 節點和 worker 節點&#xff0c;節點可以是虛擬機也可以是物理機。K8S組件 master 節點組件Kube-apiserver 用于暴露 Kubernetes API&#xff0c;任何資源請求或調用操作都是通…

PyTorch API 5

文章目錄torch.compiler延伸閱讀torch.fft快速傅里葉變換輔助函數torch.func什么是可組合的函數變換&#xff1f;為什么需要可組合的函數變換&#xff1f;延伸閱讀torch.futurestorch.fx概述編寫轉換函數圖結構快速入門圖操作直接操作計算圖使用 replace_pattern() 進行子圖重寫…

基于決策樹模型的汽車價格預測分析

一、整體流程概覽這份代碼實現了一個完整的機器學習預測流程&#xff0c;核心目標是通過汽車的各項特征預測其價格。整體流程分為 6 個主要步驟&#xff1a;模擬生成汽車數據集&#xff08;含價格標簽&#xff09;數據預處理&#xff08;清洗、編碼、特征選擇&#xff09;探索性…

0基礎安卓逆向原理與實踐:第2章:編程基礎與工具鏈

第2章:編程基礎與工具鏈 2.1 Java編程基礎 2.1.1 Java語言特性 Java是安卓應用開發的主要語言,具有以下核心特性: mindmaproot((Java特性))面向對象封裝繼承多態抽象平臺無關字節碼JVM一次編譯到處運行內存管理自動垃圾回收堆棧管理引用類型安全性字節碼驗證安全管理器訪…

深入理解JVM內存結構:從字節碼執行到垃圾回收的全景解析

&#x1f9e0; 深入理解JVM內存結構&#xff1a;從字節碼執行到垃圾回收的全景解析 #JVM內存模型 #Java性能優化 #垃圾回收機制 #并發編程一、JVM內存結構全景圖二、線程共享區域詳解 2.1 堆&#xff08;Heap&#xff09;—— 對象生存的宇宙 存儲內容&#xff1a; 所有new創建…

用 C++ 構建高性能測試框架:從原型到生產實戰指南

用 C 構建高性能測試框架&#xff1a;從原型到生產實戰指南 ?C 測試框架的關鍵價值?&#xff1a;當你的測試需要每秒處理百萬級交易&#xff0c;微秒級延遲要求已成為常態時&#xff0c;Python GC 的暫停便是不可接受的奢侈。 本文將深入探討如何用 C 構建兼具靈活性和高性能…

【C語言16天強化訓練】從基礎入門到進階:Day 4

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題、洛谷刷題、C/C基礎知識知識強化補充、C/C干貨分享&學習過程記錄 &#x1f349;學習方向&#xff1a;C/C方向 ??人…