如何在Laravel中使用Events和Listeners发送用户注册欢迎邮件?
Laravel 新用户注册自动发欢迎邮件(Events & Listeners 实现步骤)
1. 定义新用户注册事件
首先用Artisan命令快速生成事件类:
php artisan make:event UserRegistered
生成的文件位于app/Events/UserRegistered.php,修改内容将新注册的User实例注入事件,方便监听器获取用户信息:
<?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 $user; /** * 创建事件实例 * * @param \App\Models\User $user * @return void */ public function __construct(User $user) { $this->user = $user; } }
2. 创建发送欢迎邮件的监听器
第一步:生成欢迎邮件类
先做邮件内容模板,用Artisan生成邮件类:
php artisan make:mail WelcomeEmail
生成的文件位于app/Mail/WelcomeEmail.php,修改内容接收User实例并传递到视图:
<?php namespace 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; public $user; /** * 创建邮件实例 * * @param \App\Models\User $user * @return void */ public function __construct(User $user) { $this->user = $user; } /** * 构建邮件内容 * * @return $this */ public function build() { return $this->subject('欢迎加入我们的平台!') ->view('emails.welcome'); // 对应视图文件路径 } }
接着创建邮件视图resources/views/emails/welcome.blade.php,编写邮件内容:
<!DOCTYPE html> <html> <head> <title>欢迎邮件</title> </head> <body> <h1>您好,{{ $user->name }}!</h1> <p>感谢您注册我们的平台,期待您的使用!</p> </body> </html>
第二步:生成监听器类
用Artisan命令生成绑定到UserRegistered事件的监听器:
php artisan make:listener SendWelcomeEmail --event=UserRegistered
生成的文件位于app/Listeners/SendWelcomeEmail.php,修改handle方法处理邮件发送逻辑:
<?php namespace App\Listeners; use App\Events\UserRegistered; use App\Mail\WelcomeEmail; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Support\Facades\Mail; class SendWelcomeEmail { /** * 创建监听器实例 * * @return void */ public function __construct() { // 可注入依赖服务,Laravel会自动处理 } /** * 处理事件 * * @param \App\Events\UserRegistered $event * @return void */ public function handle(UserRegistered $event) { // 从事件中获取用户实例,发送邮件 Mail::to($event->user->email)->send(new WelcomeEmail($event->user)); } }
如果想要异步发送邮件(避免阻塞注册请求),只需让监听器实现ShouldQueue接口即可:
class SendWelcomeEmail implements ShouldQueue { // 原有代码不变 }
3. 注册事件与监听器,触发事件
第一步:注册事件监听器映射
打开app/Providers/EventServiceProvider.php,在$listen数组中添加事件与监听器的对应关系:
<?php namespace App\Providers; use App\Events\UserRegistered; use App\Listeners\SendWelcomeEmail; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { /** * 应用的事件监听器映射 * * @var array */ protected $listen = [ UserRegistered::class => [ SendWelcomeEmail::class, ], ]; /** * 注册任何应用事件 * * @return void */ public function boot() { parent::boot(); } }
第二步:触发事件
有两种常见触发方式,按需选择:
方式一:在注册控制器中手动触发
如果使用Laravel自带的注册控制器app/Http/Controllers/Auth/RegisteredUserController.php,在用户创建成功后触发事件:
<?php namespace App\Http\Controllers\Auth; use App\Events\UserRegistered; use App\Http\Controllers\Controller; use App\Models\User; use App\Providers\RouteServiceProvider; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Validation\Rules; class RegisteredUserController extends Controller { /** * 处理用户注册请求 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\RedirectResponse */ public function store(Request $request): RedirectResponse { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); // 触发自定义的注册事件 event(new UserRegistered($user)); Auth::login($user); return redirect(RouteServiceProvider::HOME); } }
方式二:利用模型生命周期自动触发
如果希望任何场景下创建User都触发事件,可在User模型的boot方法中添加观察者:
<?php namespace App\Models; use App\Events\UserRegistered; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Factories\HasFactory; class User extends Authenticatable { use HasFactory, Notifiable; /** * 模型启动方法 * * @return void */ protected static function boot() { parent::boot(); // 用户创建成功后自动触发事件 static::created(function ($user) { event(new UserRegistered($user)); }); } // 模型原有代码不变 }
内容的提问来源于stack exchange,提问作者vahid balanchi
相关产品推荐
相关产品推荐

