laravel9 自定义事件&监听&队列 使用
事件
一、自动生成
1、在App\Providers\EventServiceProvider文件中的$listen数组中添加事件 (作为键) 和对应的监听器 (值)
代码:protected $listen = [RegisterUser::class => [CreateImUser::class]];
2、生成事件与监听器
#事件类一般来说存储在 app/Events 目录,监听者的类存储在 app/Listeners 目录。如应用中没有这两个目录, Artisan 命令在创建事件和监听者的时候目录会同时被创建。
命令:php artisan event:generate
二、手动生成
1.手动生成事件与监听器
命令:
php artisan make:event RegisterUser
php artisan make:listener CreateImUser --event=RegisterUser
2.手动注册事件与监听
方式①:在App\Providers\EventServiceProvider文件中的$listen数组中添加事件 (作为键) 和对应的监听器 (值)
代码:protected $listen = [RegisterUser::class => [CreateImUser::class]];
方式②:在App\Providers\EventServiceProvider文件中的boot
方法中手动注册基于类或闭包的事件监听器
三、使用
事件监听器还可以在构造函数中加入任何依赖关系的类型提示。所有的事件监听器都是通过 Laravel 的 服务器容器 解析的,因此所有的依赖都将会被自动注入
如:事件类中 $paramArr 为自定义变量,在__construct方法中初始化变量,在监听器类handle方法中 通过$event->paramArr直接使用
四、事件自动发现及修改监听器目录
五、停止事件
停止将事件传播到其他侦听器。你可以通过从监听器的 handle
方法返回 false
public function handle(OrderShipped $event) {
return false;
}
六、同步处理及异步队列处理事件
指定监听器启动队列(异步处理),请将 ShouldQueue
接口添加到监听器类
① 同步处理:不实现ShouldQueue接口
② 异步队列处理:实现ShouldQueue接口 (implements ShouldQueue)即可
需要使用 php artisan queue:work 执行队列任务,才是真正执行 CreateImUser 这个监听器的 handle 方法。
七、分发事件
方式① :调用事件的静态 dispatch
方法。传递给 dispatch
方法的所有参数都会被传递给事件构造器
RegisterUser::dispatch($data);
或 延时分发
RegisterUser::dispatch($data)->delay(now()->addMinutes(10)); //10分钟后执行
或同步分发
RegisterUser::dispatchNow($data);
方式②:使用全局 event() 方法分发
event(new RegisterUser($data));
方式③:延时分发
八:失败处理
方式①:不处理失败队列,可在env文件中设置QUEUE_FAILED_DRIVER=null
方式②:处理失败队列,可以在任务类上定义一个 failed
方法。导致作业失败的 Throwable
实例将被传递给 failed
方法。
例:public function failed(Throwable $exception) {
// 向用户发送失败通知等...
}
方式③:处理失败队列,可以使用 Queue
门面的 failing
方法,在app/Providers/AppServiceProvider.php 的boot方法中为这个事件附加一个闭包。
例:Queue::failing(function (JobFailed $event) {
// $event->connectionName
// $event->job
// $event->exception
});
九:手动处理队列
1.手动将任务发布回队列,以便稍后再次尝试。你可以通过调用 release
方法来完成此操作。
$this->release();
或 通过向 release
方法传递一个整数,指示队列在给定的秒数过去之前不使任务可用于处理。
$this->release(10);
2.手动将任务失败
$this->fail();
或 想将你的任务标记为由于你捕获的异常而失败,你可以将异常传递给 fail 方法:
$this->fail($exception);
3.手动讲任务删除
$this->delete(); //在任务中使用 $this->delete()
方法删除任务不会阻止链式任务的处理。只有当链中的任务失败时,链才会停止执行
注意:use Illuminate\Queue\SerializesModels;
Events中 初始化方法中接受的参数,接收到一个 Eloquent ORM 对象时,如果事件对象是使用 PHP 的 SerializesModels 函数序列化的,事件使用的 SerializesModels trait 将会优雅地序列化任何 Eloquent 模型.
向任务中注入 Eloquent 模型时,模型会在注入队列之前自动序列化,并在处理任务时从数据库中重新检索。但是,如果在任务等待消费时删除了模型,则任务可能会失败,抛出 ModelNotFoundException 异常
解决方法:
1、删除SerializesModels的使用,可避免抛出异常,
2、避免传递Eloquent 模型,可将Eloquent 模型 toArray(), 转换成数组进行传递