laravel 事件系统的初衷是为了处理一些完成后的操作,比如注册成功后发送邮箱通知,或者是订单发货之后进行短信通知。这些操作可以和之前的状态修改代码分开写,为了实现解耦的目的,一般会在类里面再写一个function,然后再状态修改代码之后调用这个function。然而laravel实现了一个监听/调用的事件系统,不用在同类的代码下再写一个function。而是直接和状态修改代码直接分开了。并且事件系统和队列系统一起用还实现了异步代码的效果。
使用laravel的事件首先需要创建监听类和事件类。根据文档,在app/Providers/EventServiceProvider.php 文档里,添加你所需要新增的监听器和事件,比如这样
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
'App\Events\OrderShipped' => [
'App\Listeners\SendShipmentNotification',
],
];
这里是事件为key,监听器为value。配置好之后执行
php artisan event:generate
之后框架就会在app目录下生成Events目录和Listeners目录,并在下面生成OrderShipped.php和SendShipmentNotification.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 OrderShipped
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public $string;
public function __construct($string)
{
//
$this->string = $string;
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
监听器,在监听器里可以通过调用$event的属性,来获取代码在事件里传入的数据。
<?php
namespace App\Listeners;
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class SendShipmentNotification
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param OrderShipped $event
* @return void
*/
public function handle(OrderShipped $event)
{
//
sleep(2);
file_put_contents("test.txt",$event->string.date("Y-m-d H:i:s"),FILE_APPEND);
}
}
使用事件需要用event函数
public function index()
{
$data = ['test1','test2'];
foreach ($data as $item) {
event(new OrderShipped($item));
}
return response()->json(['code'=>0, 'msg'=>"success","data"=>date("Y-m-d H:i:s")]);
}
这里我通过 event(new OrderShipped($item));调用了我之前注册的事件。然后请求页面,页面显示加载了4秒,再显示
然后test.txt也新增了对应字段。