Laravel 5.1中定义事件、事件监听器以及触发事件例子
这里我们基于之前基于模型 缓存对文章增删改查这篇文件对文章保存后缓存的处理做进一步优化。我们将文章保存(新建/修改)视为一个事件,将保存文章内容到缓存放到监听器中实现:
1、注册事件-监听器
首先我们需要在EventServiceProvider中注册事件与监听器之间的映射关系:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8154')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8154>protected $listen = [
'App\Events\PostSaved'=>[
'App\Listeners\SaveDataToCache'
]
];
然后我们在项目根目录运行如下Artisan命令:
php artisan event:generate
该命令会在app/Events目录下生成PostSaved.php,在app/Listeners目录下生成SaveDataToCache.php。
2、定义事件类
接下来我们编辑事件类PostSaved如下:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy2396')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy2396><?php
namespace App\Events;
use App\Events\Event;
use App\Models\Post;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class PostSaved extends Event
{
use SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Post $post)
{
$this->post = $post;
}
/**
* Get the channels the event should be broadcast on.
*
* @return array
*/
public function broadcastOn()
{
return [];
}
}
我们在构造函数中注入一个Post实例传递给PostSaved。
3、定义监听器类
然后我们来定义监听器类SaveDataToCache,监听器类中使用handle方法接收事件实例并执行响应该事件的业务逻辑,这里就是将就接收到的Post实例保存到缓存中:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8918')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8918><?php
namespace App\Listeners;
use App\Events\PostSaved;
use Cache;
use Log;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SaveDataToCache
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param PostSaved $event
* @return void
*/
public function handle(PostSaved $event)
{
$post = $event->post;
$key = 'post_'.$post->id;
Cache::put($key,$post,60*24*7);
Log::info('保存文章到缓存成功!',['id'=>$post->id,'title'=>$post->title]);
}
}
业务逻辑很简单:从注入的PostSaved中获取文章实例并将其保存到缓存,并将该操作记录到日志。
4、触发事件
最后我们来测试文章保存事件及其监听器。
要触发文章保存事件,可以使用Event门面提供的fire方法,在PostController中修改store方法如下:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy9695')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy9695>public function store(Request $request)
{
$title = $request->input('title');
$content = $request->input('content');
$post = new Post;
$post->title = $title;
$post->content = $content;
$post->save();
Event::fire(new PostSaved($post));
return redirect()->route('post.show',['post'=>$post]);
}
然后修改update方法如下:
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy2245')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy2245>public function update(Request $request, $id)
{
$post = Post::find($id);
if(!$post)
exit('指定文章不存在!');
$title = $request->input('title');
$content = $request->input('content');
$post->title = $title;
$post->content = $content;
$post->save();
Event::fire(new PostSaved($post));
return redirect()->route('post.show',['post'=>$post]);
}
在浏览器中访问http://laravel.app:8000/post/create,填写标题和文章内容:
点击提交页面跳转到文章详情页,此时去查看日志storage/logs/laravel.log,可以看到对应日志记录:
[2015-11-10 23:14:12] local.INFO: 保存文章到缓存成功! {"id":13,"title":"Test Event Add"}
说明已触发文章保存事件,监听器监听到事件后将其保存到缓存中并记录日志。
您可能感兴趣的文章:
Node.js EventEmitter
Laravel 5.1中定义事件、事件监听器以及触发事件例子
JavaScript监听IME键盘输入事件实例详解
不要使用jQuery触发原生事件的方法
jQuery 事件的命名空间
Laravel 的 Events 及 Observers 模型事件学习笔记
JavaScript HTML DOM EventListener
js屏蔽默认快捷键调用自定义事件的代码
解密jQuery事件核心 – 自定义设计(三)
jquery中的事件处理详细介绍