Event
与 Listener
两者不可分割,是要结合在一起使用的,触发 一个 Event ,下面绑定的 Listeners 就会跟着触发
。Event
& Listener
就可以派上用场,所以本质上就是将多个功能抽象提取出来放到 Event
& Listener
来达到解耦及复用效果。场景:比如用户注册成功后发送邮箱给用户,我们就可以把发送邮箱客户当做一个 event,下面我们来开始写代码。
app/Providers/EventServiceProvider.php
里面有个 $listene
变量,我们可以在里面定义 Event 和 Listneruse App\Events\RegisterEvent; use App\Listeners\SendEmailListener; protected $listen = [ // Laravel 自带的 Registered::class => [ SendEmailVerificationNotification::class, ], // 自定义 RegisterEvent::class => [ SendEmailListener::class, ], // 每个 Event 还可以 1 对多个 Listener // RegisterEvent::class => [ // SendEmailListener::class, // RecordUserListener::class // ], ];
php artisan event:generate
,此命令会根据上面自定义的 Event 和 Listener 生成对应的文件,其中 RegisterEvent 对应 app/Events/RegisterEvent.php
,而 SendEmailListener 对应 app/Listeners/SendEmailListener.php
,这两个文件代码如下// app/Events/RegisterEvent.php ============================== <?php namespace App\Events; use Illuminate\Broadcasting\Channel; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Broadcasting\PresenceChannel; use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class RegisterEvent { use Dispatchable, InteractsWithSockets, SerializesModels; public $user; // 1. 随便自定义变量 public function __construct($user) { // 2. 然后初始化接受,最后会传递给所有绑定的 Listener。 $this->user = $user; } // 这里是其它用途,我们暂时不用管,后续我会在讲解。 public function broadcastOn() { return new PrivateChannel('channel-name'); } } // app/Listeners/SendEmailListener.php ============================== <?php namespace App\Listeners; use App\Events\RegisterEvent; // 引入 RegisterEvent 事件 use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; class SendEmailListener { /** * Create the event listener. * * @return void */ public function __construct() { // } /** * Handle the event. * * @param \App\Events\LoginHistory $event * @return void */ public function handle(RegisterEvent $event) { // 接受 RegisterEvent 传递过来的 user。 $user= $event->user; // 发送邮箱处理逻辑,为了演示效果这里我们就简单打印下 // ... echo "Touch"; var_dump($user); } }
php artisan make:controller RegisterController
在 app\Http\Controllers
下创建 RegsiterController.php,并在RegisterController.php
和 route/web.php
中编写如下代码// app/Http/Controllers/RegisterController.php ============================== <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Events\RegisterEvent; // 引入 RegisterEvent 事件 class RegisterController extends Controller { // public function __construct() { } public function register() { $user = [ 'user' => 'cookcyq', 'password' => '123456' ]; // 安心编写我们的注册逻辑 // .... // 注册完成后,触发事件。 event(new RegisterEvent($user)); } } // route/web.php ============================== use Illuminate\Support\Facades\Route; use App\Http\Controllers\RegisterController; Route::get('/register', [RegisterController::class, 'register']);
Note: 如果你会 Javascript 和 html 其实也间接理解了 Laravel 的 Events & Listeners ,工作原理是一样的。
<input type='file' id="upload" value="上传"/> <script> const upload = document.getElementById('upload) const postEmailListener = () => { alert('postEmailListener') } const recordListener = () => { alert('recordListener') } upload.addEventListener('change', postEmailListener) upload.addEventListener('change', recordListener) </script>
当我们[上传]文件时,系统会自动触发 change 事件,然后我们在通过 addEventListener 来监听 change 事件。
参考文献
https://dev.to/kingsconsult/laravel-8-events-and-listeners-with-practical-example-9m7