Laravel 事件系统用法总结(监听事件,观察者模式)
看这篇文章先复习一下设计模式 : https://www.cnblogs.com/fps2tao/p/9640338.html
在理解了观察者模式后,我们开始正文
Laravel 的事件提供了一个简单的观察者实现,能够订阅和监听应用中发生的各种事件。事件类保存在 app/Events 目录中,而这些事件的的监听器则被保存在 app/Listeners 目录下。这些目录只有当你使用 Artisan 命令来生成事件和监听器时才会被自动创建。
事件机制是一种很好的应用解耦方式,因为一个事件可以拥有多个互不依赖的监听器。例如,如果你希望每次订单发货时向用户发送一个 Slack 通知。你可以简单地发起一个 OrderShipped 事件,让监听器接收之后转化成一个 Slack 通知,这样你就可以不用把订单的业务代码跟 Slack 通知的代码耦合在一起了。
手动生成一个事件
比如通过 artisan 命令手动生成一个 UserLogin 事件:
php artisan make:event UserLogin
在 app/Events 中就会自动生成一个 UserLogin.php 文件,内容不多,如下:
<?php namespace App\Events; use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast; class UserLogin
{
use InteractsWithSockets, SerializesModels; /**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
} /**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
定义监听器
一个事件可以被一个或多个监听器监听,也就是观察者模式,我们可以定义多个监听器,当这个事件发生,执行一系列逻辑。
在 EventServiceProvider 的 $listen 中可以定义事件和监听器,如下:
protected $listen = [
'App\Events\UserLogin' => [
'App\Listeners\DoSomething1',
'App\Listeners\Dosomething2',
],
];
执行 artisan 命令,就可以自动在 app/Lisenter 目录生成监听器。
php artisan event:generate
这个命令也可以自动生成事件,如果没有 UserLogin 这个事件会自动生成,而不需要手动生成。
可以看到 app/Listeners 目录多了 DoSomething1.php 和 DoSomething2.php 两个文件,我们看看其中一个内容:
<?php namespace App\Listeners; use App\Events\UserLogin;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue; class DoSomething1
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
} /**
* Handle the event.
*
* @param UserLogin $event
* @return void
*/
public function handle(UserLogin $event)
{
info('do something1');
}
}
在两个监听器的 handle 方法中我们打印一个日志来测试一下,如代码 handle 方法所示。
分发和触发事件
我们在某个控制器的方法中来分发事件,也就是触发事件,看监听器是否正常工作。
就是一句话:
event(new UserLogin());
然后我们请求这个控制器,观察日志,发现打印了日志:
[2018-06-17 10:04:29] local.INFO: do something1
[2018-06-17 10:04:29] local.INFO: do something2
那么这个事件-监听机制就正常工作了。
队列异步处理
如果某个监听器需要执行的操作比较慢,可以放到消息队列进行异步处理。
比如把上面的 DoSomething1 改成需要放入队列的,只需要 implements ShoulQueue 接口。
class DoSomething1 implements ShouldQueue
也可以指定队列驱动,如下代码。
/**
* 任务应该发送到的队列的连接的名称
*
* @var string|null
*/
public $connection = 'redis'; /**
* 任务应该发送到的队列的名称
*
* @var string|null
*/
public $queue = 'listeners';
我们再次执行控制器方法。
日志里没有打印 do something1,只有 do something2,但是在 redis 队列里发现了一个名为 queues:default 的列表。
{"job":"Illuminate\\Events\\CallQueuedHandler@call","data":{"class":"App\\Listeners\\DoSomething1","method":"handle","data":"a:1:{i:0;O:20:\"App\\Events\\UserLogin\":1:{s:6:\"socket\";N;}}"},"id":"3D7VDUwueYGtUvsazicWsifwWQxnnLID","attempts":1}
这个时候需要使用 php artisan queue:work 执行队列任务,才是真正执行 DoSomething1 这个监听器的 handle 方法。
参考链接
转: https://blog.tanteng.me/2018/06/laravel-event/
参考 : https://www.jianshu.com/p/89ae2b78dd91
相关阅读: https://www.cnblogs.com/fps2tao/p/9681455.html
参考 设计模式 : https://www.cnblogs.com/fps2tao/p/9640338.html
Laravel 事件系统用法总结(监听事件,观察者模式)的更多相关文章
- spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- Second Day: 关于Button监听事件的三种方法(匿名类、外部类、继承接口)
第一种:通过匿名类实现对Button事件的监听 首先在XML文件中拖入一个Button按钮,并设好ID,其次在主文件.java中进行控件初始化(Private声明),随后通过SetOnClickLis ...
- springboot13 发布和监听事件
spring中的事件驱动模型Event(也叫发布订阅模式),是观察者模式的一个典型的应用 好处:业务解耦,在不影响原来业务逻辑的情况下,加入其它业务 场景: app上线后已实现用户注册功能,现需要在用 ...
- DOM初体验(绑定事件,监听事件)
JavaScript的组成: ECMAScript(js的基本语法).DOM(文档对象模型).BOM(浏览器对象模型) DOM的作用: 1. 找到页面上的元素 2. 增添.删除.修改页面上的元素 3. ...
- Android中Button的五种监听事件
简单聊一下Android中Button的五种监听事件: 1.在布局文件中为button添加onClick属性,Activity实现其方法2.匿名内部类作为事件监听器类3.内部类作为监听器4.Activ ...
- js 获取当前焦点所在的元素、给元素和input控件添加键盘监听事件、添加页面级的键盘监听事件
页面级的键盘监听事件 document.onkeydown = function (event) { var e = event || window.event || arguments.callee ...
- android listview 的监听事件
今天遇到了一个比较让我头疼的问题,不过追根揭底只是我对listview理解的不够透彻罢了, 闲言少叙,说说我遇到的问题吧: 上篇随笔我写了关于listview的使用,如果你也已经写好了列表那么恭喜这一 ...
- Android成长日记-Android监听事件的方法
1. Button鼠标点击的监听事件 --setOnClickListener 2. CheckBox, ToggleButton , RadioGroup的改变事件 --setOnCheckedCh ...
- Vue 为什么在 HTML 中监听事件?
为什么在 HTML 中监听事件? 你可能注意到这种事件监听的方式违背了关注点分离(separation of concern)传统理念.不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑 ...
随机推荐
- windows CMD命令查看局域网内所有主机名及IP
COLOR 0A CLS @ECHOOff Title查询局域网内在线电脑IP :send @ECHO off&setlocal enabledelayedexpansion ECHO 正在获 ...
- Java Object Clone
Java Object Clone User user = new User(); user.setName("tom"); User user1 = new User(); us ...
- Office EXCEL VBA如何取得EXCEL中的行数和列数
VBA取得EXCEL表格中的行数和列数 请注意不要使用Columus等关键字作为变量,例如"Columus = ActiveSheet.UsedRange.Columns.Count&quo ...
- 搭建一个SpringBoot项目
1.创建项目 New->Spring Starter Project 2.添加支持 增加对mybatis plus的支持,修改pom.xml,增加如下内容: <dependency> ...
- 栈的应用实例——平衡符号
检查().[].{}是否配对. /* stack_balance_symbol */ #include "stack.h" #include <stdio.h> #in ...
- Unix时间戳转换
import time def timestamp_datetime(value): format = '%Y-%m-%d %H:%M:%S' # value为传入的值为时间戳(整 ...
- rpx单位与移动设备分辨率
移动设备的分辨率与rpx 不是所有的单位都适合用rpx 文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论
- 采集的时候,列表的编码是gb2312,内容页的编码却是UTF-8,这种网站怎么采集?
采集的时候,列表的编码是gb2312,内容页的编码却是UTF-8,这种网站怎么采集? 采集的时候,列表的编码是UTF-8,内容页的编码却是gb2312,这种网站怎么采集? 这种情况怎么解决呢? 哈哈哈 ...
- PHP $_POST
$_POST 变量用于收集来自 method="post" 的表单中的值. $_POST 变量 $_POST 变量是一个数组,内容是由 HTTP POST 方法发送的变量名称和值. ...
- 腾讯地图api将物理地址转化成坐标
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...