laravel 事件/监听器实例代码


Posted in PHP onApril 12, 2019

导语

上一篇文章实现了记录用户访问,设计上是有缺陷的,代码紧耦合在中间件。如果后续修改需求,不仅记录 ip、城市,还需要记录数据到新的数据表,或者需要进行其它统计,那么不停的增加、修改代码是不合理的。这个时候可以使用 Laravel 的事件/监听器进行处理。代码可查看 GitHub。

事件/监听器

Laravel 事件提供了简单的观察者模式实现,允许你订阅和监听应用中的事件。

观察者模式有时也被称作发布/订阅模式,该模式用于为对象实现发布/订阅功能:一旦主体对象状态发生改变,与之关联的观察者对象会收到通知,并进行相应操作。

以上是事件/监听器、观察者模式的简要说明。结合这次的需求理解,当触发用户访问事件,它的观察者进行处理。观察者可以是多个,本例仅做入库操作。

创建事件/监听器

在 app/Providers/EventServiceProvider.php 文件中添加事件/监听器,如下

/**
   * The event listener mappings for the application.
   *
   * @var array
   */
  protected $listen = [
    Registered::class => [
      SendEmailVerificationNotification::class,
    ],
    'App\Events\UserBrowse' => [
      'App\Listeners\CreateBrowseLog',
      // 其它监听器
    ],
  ];

添加好之后,执行 php artisan event:generate,会自动创建对应的事件/监听器。分别创建了 app/Events/UserBrowse.php 和 app/Listeners/CreateBrowseLog.php 两个文件。

实现代码

把目光聚集到事件 app/Events/UserBrowse.php 文件,这里需要接收数据以便后续处理,代码如下

public $ip_addr;
  public $request_url;
  public $city_name;

  /**
   * Create a new event instance.
   *
   * @return void
   */
  public function __construct($ip_addr, $request_url, $city_name)
  {
    $this->ip_addr = $ip_addr;
    $this->request_url = $request_url;
    $this->city_name = $city_name;
  }

然后是监听器 app/Listeners/CreateBrowseLog.php,这里要做的是,将事件中接收到的数据进行入库操作,代码如下

/**
   * Handle the event.
   *
   * @param UserBrowse $event
   * @return void
   */
  public function handle(UserBrowse $event)
  {
    $log = new \App\Models\BrowseLog();

    $log->ip_addr = $event->ip_addr;
    $log->request_url = $event->request_url;
    $log->city_name = $event->city_name;

    $log->save();
  }

分发事件

最后就是分发事件,修改 app/Http/Middleware/BrowseLog.php 中间件的代码,修改后如下

/**
   * Handle an incoming request.
   *
   * @param \Illuminate\Http\Request $request
   * @param \Closure $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {
    // 使用事件/监听器入库
    event(new UserBrowse($request->getClientIp(), $request->path(), get_city_by_ip(false, 'null')));
    
    return $next($request);
  }

测试之后是没有问题的。

结语

这次所做的修改,感官上来看,就是将入库操作从中间件转移到监听器中,实际上的意义远不止于此。例如同一个事件,可以分发在不同的地方;事件添加了需求,只需要在添加一个监听器即可;监听器中也可以使用队列等等。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php在线打包程序源码
Jul 27 PHP
PHP程序员面试 切忌急功近利(更需要注重以后的发展)
Sep 01 PHP
php遍历数组的4种方法总结
Jul 05 PHP
CentOS下PHP安装Oracle扩展
Feb 15 PHP
Ubuntu中启用php的mail()函数并解决发送邮件速度慢问题
Mar 27 PHP
Yii快速入门经典教程
Dec 28 PHP
PHP中Restful api 错误提示返回值实现思路
Apr 12 PHP
Zend Framework数据库操作技巧总结
Feb 18 PHP
PHP strripos函数用法总结
Feb 11 PHP
PHP数据源架构模式之表入口模式实例分析
Jan 23 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 PHP
php实现统计IP数及在线人数的示例代码
Jul 22 PHP
Laravel5.7 数据库操作迁移的实现方法
Apr 12 #PHP
laravel使用Faker数据填充的实现方法
Apr 12 #PHP
Laravel5.7 Eloquent ORM快速入门详解
Apr 12 #PHP
laravel 数据迁移与 Eloquent ORM的实现方法
Apr 12 #PHP
PHP中的Iterator迭代对象属性详解
Apr 12 #PHP
PHP中str_split()函数的用法讲解
Apr 11 #PHP
PHP远程连接oracle数据库操作实现方法图文详解
Apr 11 #PHP
You might like
PHP 截取字符串函数整理(支持gb2312和utf-8)
2010/02/16 PHP
PHP5与MySQL数据库操作常用代码 收集
2010/03/21 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
2010/12/29 PHP
ThinkPHP3.1新特性之字段合法性检测详解
2014/06/19 PHP
php设计模式之委托模式
2016/02/13 PHP
laravel自定义分页效果
2017/07/23 PHP
php strftime函数的详细用法
2018/06/21 PHP
JavaScript 变量基础知识
2009/11/07 Javascript
js定义对象或数组直接量时各浏览器对多余逗号的处理(json)
2011/03/05 Javascript
javascript中取前n天日期的两种方法分享
2014/01/26 Javascript
jQuery获得子元素个数的方法
2015/04/14 Javascript
js实现新浪微博首页效果
2015/10/16 Javascript
漂亮! js实现颜色渐变效果
2016/08/12 Javascript
Bootstrap基本组件学习笔记之面板(14)
2016/12/08 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
2017/02/13 Javascript
JS控件bootstrap datepicker使用方法详解
2017/03/25 Javascript
Angularjs验证用户输入的字符串是否为日期时间
2017/06/01 Javascript
jQuery Jsonp跨域模拟搜索引擎
2017/06/17 jQuery
jquery中ajax请求后台数据成功后既不执行success也不执行error的完美解决方法
2017/12/24 jQuery
bootstrap-table+treegrid实现树形表格
2019/07/26 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
解决antd datepicker 获取时间默认少8个小时的问题
2020/10/29 Javascript
Python切割图片成九宫格的示例代码
2020/03/10 Python
python如何对链表操作
2020/10/10 Python
Python3 + Appium + 安卓模拟器实现APP自动化测试并生成测试报告
2021/01/27 Python
一款基于css3麻将筛子3D翻转特效的实例教程
2014/12/31 HTML / CSS
AmazeUI导航的示例代码
2020/08/14 HTML / CSS
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
《藏戏》教学反思
2014/02/11 职场文书
英语国培研修感言
2014/02/13 职场文书
电子商务求职信
2014/06/15 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
毕业实习指导教师评语
2014/12/31 职场文书
销售开票员岗位职责
2015/04/15 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
基于PostgreSQL/openGauss 的分布式数据库解决方案
2021/12/06 PostgreSQL