Laravel发送邮件报错:参数需为Mailable类型而非Livewire组件
问题:Laravel Livewire实现密码重置时邮件发送报错
报错信息
Illuminate\Mail\PendingMail::send(): Argument #1 ($mailable) must be of type Illuminate\Contracts\Mail\Mailable, App\Http\Livewire\Auth\ResetPassword given, called in /Users/andreiraileanu/Development/Protein/app/Http/Livewire/Auth/ResetPassword.php
Livewire重置密码组件代码
<?php namespace App\Http\Livewire\Auth; use Livewire\Component; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; use Illuminate\Support\Facades\Mail; use App\Models\User; class ResetPassword extends Component { public $email; public $phone; protected $user; protected $rules = [ 'email' => 'required|email', 'phone' => 'required|digits:10', ]; public function submit() { $this->validate(); $this->user = User::where('email', $this->email) ->where('phone', $this->phone) ->first(); if ($this->user) { \Debugbar::info('Identified User ID: '.$this->user->id); $this->user->password = Str::random(8); \Debugbar::info('New password is: '.$this->user->password); $this->user->password = Hash::make($this->user->password); $this->user->save(); \Debugbar::info('Password saved!'); Mail::to($this->user->email)->send(new ResetPassword($this->user)); } else { $this->dispatchBrowserEvent('notify', ['content' => 'Adresa de email nu există sau numărul de telefon este incorect', 'type' => 'error']); \Debugbar::error('Wrong email and/or phone number.'); } } public function render() { return view('livewire.auth.reset-password'); } }
Mailable类代码
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use App\Models\User; class ResetPassword extends Mailable { use Queueable, SerializesModels; protected $user; public function __construct(User $user) { $this->user = $user; } public function build() { return $this->subject('Order Shipped') ->view('emails.auth.reset-password'); } }
用户疑问:请问我哪里操作错误?此前从未遇到该问题。
错误原因与修复方法
错误原因
执行Mail::to(...)->send(new ResetPassword($this->user))时,实例化的ResetPassword是当前Livewire组件类(App\Http\Livewire\Auth\ResetPassword),而非你定义的Mailable邮件类(App\Mail\ResetPassword)。两个类同名且Livewire组件文件未引入正确的Mailable类,PHP默认使用了当前命名空间下的类,导致类型不匹配报错。
修复方法
有两种解决方式:
方法1:引入Mailable类并使用别名
在Livewire组件文件顶部添加Mailable类的引入,并用别名避免混淆:
// 在现有use语句后添加 use App\Mail\ResetPassword as ResetPasswordMail;
修改发送邮件的代码:
Mail::to($this->user->email)->send(new ResetPasswordMail($this->user));
方法2:直接使用完整命名空间实例化
无需额外引入,直接写全Mailable类的命名空间:
Mail::to($this->user->email)->send(new \App\Mail\ResetPassword($this->user));
额外建议
邮件主题Order Shipped(订单已发货)与密码重置场景不符,建议修改为相关主题,比如:
return $this->subject('你的账户密码已重置') ->view('emails.auth.reset-password');
内容的提问来源于stack exchange,提问作者Andrei RRR
相关产品推荐
相关产品推荐

