利用Laravel事件系统如何实现登录日志的记录详解_php技巧_脚本之家

正文介绍的是应用Laravel事件系统实现登入日志记录的相干内容,共享出来给大家仿照效法,下边来看看详细的牵线:

简介

Laravel事件提供了简短的旁观者方式完成,允许你订阅和监听应用中的事件。事件类日常存放在app/Events目录,监听器寄存在app/Listeners。
在乎区分旧的laravel版本。下图为laravel5.1的晋级表明。

金沙8331网址 1

众目昭彰须要

挂号事件和监听器

大家能够在app/Providers/目录下的伊夫ntServiceProvider中注册事件和监听器映射关系,当中的listen属性包括了事件(键)和呼应监听器(值)数组。若是运用须要,你可以增添多少个事件到该数组。举个例子,让大家增加StockChange伊芙nt事件和StockChangeListener:

/**
 * 事件监听器映射
 *
 * @var array
 */
protected $listen = [
    'SharkEventsProductStockChangeEvent' => [
        'SharkListenersProductStockChangeListener',
    ],
    'SharkEventsProductProductAddEvent' => [
        'SharkListenersProductProductListener',
        'SharkListenersProductProductAddListener',
    ],
];

本来你也足以二个平地风波绑定四个监听器。
你也足以选取下面包车型客车不二等秘书籍注册事件和监听器:

Event::listen('SharkEventsProductStockChangeEvent', 'SharkListenersProductStockChangeListener');

你也能够选择下边的办法消灭事件监听器的绑定

Event::forget('SharkEventsProductStockChangeEvent');

记录多少个记名日志,平时要求下列音信:

概念事件和监听器

你可以应用artisan make:event 和artisan
make:listener生成对应的文本,你也能够采取artisan event:generate
前提是您先在EventServiceProvider中登记好事件。

<?php

namespace SharkEventsProduct;

use SharkEventsEvent;
use IlluminateQueueSerializesModels;

class StockChangeEvent extends Event
{
    use SerializesModels;
    protected $product_id = 0;
    protected $sku_id = 0;

    /**
     * StockChangeEvent constructor.
     * @param $product_id
     * @param $sku_id
     */
    public function __construct($product_id, $sku_id)
    {
        //这里接收事件
        $this->product_id = $product_id;
        $this->sku_id = $sku_id;
        Log::alert('event', ['event' => func_get_args()]);
    }

    /**
     * Get the channels the event should be broadcast on.
     *
     * @return array
     */
    public function broadcastOn()
    {
        return [];
    }
}

<?php

namespace SharkListenersProduct;

use SharkEventsProductStockChangeEvent;
use IlluminateQueueInteractsWithQueue;
use IlluminateContractsQueueShouldQueue;

class StockChangeListener implements ShouldQueue
{
    use InteractsWithQueue;

    /**
     * 创建事件监听器.
     *
     * @return void
     */
    public function __construct()
    {
    //你的事件监听器还可以在构造器中类型提示任何需要的依赖,所有事件监听器通过服务容器解析,所以依赖会自动注入。
    }

    /**
     * 处理事件.
     *
     * @param  StockChangeEvent $event
     * @return void
     */
    public function handle(StockChangeEvent $event)
    {
        //这里写你对监听的这个事件的处理。这里你可以使用$event->product_id获取参数
        Log::alert('Listen', ['Listen' => func_get_args()]);
    }
}

注意事项:

  1. 您的风云监听器还能在布局器中类型提示任何索要的依附,所有的事件监听器通过服务容器剖析,所以重视会自行注入。
  2. 假使您的事件绑定了多个监听器,一时候,你指望甘休事件被流传到任何监听器,你可以通过从监听器的handle方法中回到false来贯彻

金沙8331网址,顾客端Agent信息 客商端IP地址 访谈IP地方 登入时间 登入客商音讯

事件监听器队列

假定您想选用异步队列的监听器,让监听器类完毕ShouldQueue接口就能够。你可以参照命令artisan
help
make:listener来生成异步的监听代码。如若直白动用event:generate生成的监听器不是异步的。
假如您利用异步监听,会写入队列queues:default中。

金沙8331网址 2

利用Laravel事件系统如何实现登录日志的记录详解_php技巧_脚本之家。当监听器被事件调用,将会动用Laravel的类别系统经过队列分发器自动队列化。即使经过队列施行监听器的时候从不抛出任何分外,队列职务在奉行到位后被电动删除。

若果您须求手动访问底层队列职责的delete和release方法,在更换的监听器中暗中认可导入的IlluminateQueueInteractsWithQueue
trait提供了访问那八个方法的权柄:

创造工具

接触事件

要接触多少个事变,可以动用伊夫nt门面,传递一个风云实例到fire方法,fire方法会分发事件到具备监听器:

Event::fire(new StockChangeEvent(1, 1));
event(new StockChangeEvent(1, 1));

以上二种写法均可。

芸芸众生完须要后,依据各种供给查找自身所需的工具吧。

其他

伊夫nt门面方法求证:

  • void listen(string|array $events, mixed $listener, int $priority)
    手动注册事件和监听器的涉及。
  • bool hasListeners(string $eventName)认清叁个平地风波是不是注册的有监听器。
  • void push(string $event, array $payload = array())Register an
    event and payload to be fired later.
  • void subscribe(object|string $subscriber)Register an event
    subscriber with the dispatcher.
  • mixed until(string $event, array $payload = array()) Fire an event
    until the first non-null response is
    returned.触发三个风浪,顺序施行监听器直到非null的响应重回。
  • void flush(string $event)Flush a set of pushed events.
  • array|null fire(string|object $event, mixed $payload = array(), bool $halt = false)
    触发事件
  • array getListeners(string $eventName) 获取叁个事件注册的享有监听器
  • void forget(string $event) 打消三个平地风波的注册器绑定(Remove a set
    of listeners from the dispatcher.)

供给1 jenssegers/agent就足以满足我们供给 须要2
Laravel下直接Request::getClientIp() 须求3
zhuzhichao/ip-location-zh那么些包能够满意供给 须求4 time() 须求5
登陆客商模型

参谋资料

  1. http://laravelacademy.org/post/198.html
  2. https://laravel.com/api/5.1/Illuminate/Events/Dispatcher.html

开工

应用Laravel的事件订阅系统来兑现,供给达成贰个记名事件和几个登陆事件监听器。

变迁事件和监听器

Laravel命令行支持自动生成事件和监听器,在AppProvidersEventServiceProvider中增多必要落到实处的风浪:

protected $listen = [ ..., //添加登录事件及对应监听器,一个事件可绑定多个监听器 'AppEventsLoginEvent' => [ 'AppListenersLoginListener', ],];

运行命令:php artisan event:generate就能够自动生成事件和监听器,已存在的风浪和监听器不会发生更动。

报到事件

回首下需求,我们的记名事件须求的5点音讯,在事件中必要记录这个音讯,所以事件设计如下:

namespace AppEvents;use IlluminateBroadcastingChannel; use IlluminateQueueSerializesModels; use IlluminateBroadcastingPrivateChannel; use IlluminateFoundationEventsDispatchable; use IlluminateBroadcastingInteractsWithSockets;use AppModelsUser; use JenssegersAgentAgent;class LoginEvent { use Dispatchable, InteractsWithSockets, SerializesModels; /** * @var User 用户模型 */ protected $user; /** * @var Agent Agent对象 */ protected $agent; /** * @var string IP地址 */ protected $ip; /** * @var int 登录时间戳 */ protected $timestamp; /** * 实例化事件时传递这些信息 */ public function __construct($user, $agent, $ip, $timestamp) { $this->user = $user; $this->agent = $agent; $this->ip = $ip; $this->timestamp = $timestamp; } public function getUser() { return $this->user; } public function getAgent() { return $this->agent; } public function getIp() { return $this->ip; } public function getTimestamp() { return $this->timestamp; } /** * Get the channels the event should broadcast on. * * @return Channel|array */ public function broadcastOn() { return new PrivateChannel; }} 

在事变中著录所急需的音讯,并落实这个音信的get方法。

登陆监听器

在监听器中,获取到事件传递过来的新闻,把这几个消息记录到数据库中,达成如下:

namespace AppListeners;use AppEventsLoginEvent;class LoginListener { // handle方法中处理事件 public function handle { //获取事件中保存的信息 $user = $event->getUser(); $agent = $event->getAgent(); $ip = $event->getIp(); $timestamp = $event->getTimestamp(); //登录信息 $login_info = [ 'ip' => $ip, 'login_time' => $timestamp, 'user_id' => $user->id ]; // zhuzhichao/ip-location-zh 包含的方法获取ip地理位置 $addresses = Ip::find; $login_info['address'] = implode; // jenssegers/agent 的方法来提取agent信息 $login_info['device'] = $agent->device(); //设备名称 $browser = $agent->browser(); $login_info['browser'] = $browser . ' ' . $agent->version; //浏览器 $platform = $agent->platform(); $login_info['platform'] = $platform . ' ' . $agent->version; //操作系统 $login_info['language'] = implode(',', $agent->languages; //语言 //设备类型 if  { // 平板 $login_info['device_type'] = 'tablet'; } else if  { // 便捷设备 $login_info['device_type'] = 'mobile'; } else if  { // 爬虫机器人 $login_info['device_type'] = 'robot'; $login_info['device'] = $agent->robot(); //机器人名称 } else { // 桌面设备 $login_info['device_type'] = 'desktop'; } //插入到数据库 DB::table->insert; } }

这么,监听器就完了了,每趟一触发登入事件,就能够在数据库中增多一条登入音讯。

接触事件

由此全局的event()措施来触发事件,event()方法的参数为事件实例:

namespace AppControllers; ...use AppEventsLoginEvent; use JenssegersAgentAgent; class AuthControoler extends Controller { ... public function login { //登录实现 ... //登录成功,触发事件 event(new LoginEvent->user, Request::getClientIp; ... } } 

队列化监听器

突发性监听器会进展一些耗费时间操作,当时应该结合Laravel的队列系统将监听器实行队列化,前提是早就铺排了队列并开启了队列微电脑。

队列化特别轻易,只需监听器完毕ShouldQueue接口就能够,即:

namespace AppListeners; ...use IlluminateContractsQueueShouldQueue; class LoginListener implements ShouldQueue { /** * 失败重试次数 * @var int */ public $tries = 1; ...} 

总结

Laravel的轩然大波系统贯彻起来依旧特别高贵的,同八个风云能够很有益的丰裕各种监听器,且种种监听器之间互不苦恼,解耦性特别强。加上队列系统,能够很实惠的拍卖部分三番两次职分。

好了,以上便是那篇小说的全部内容了,希望本文的从头到尾的经过对大家的读书也许工作能拉动一定的声援,如若有毛病我们能够留言调换,谢谢我们对台本之家的支撑。

发表评论

电子邮件地址不会被公开。 必填项已用*标注