这里有新鲜出炉的 Laravel 5.0 官方中文教程,程序狗速度看过来!
Laravel 是一套简洁、优雅的 PHP Web 开发框架 (PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络 APP,而且每行代码都可以简洁、富于表达力。
这篇文章主要给大家介绍了利用 Laravel 事件系统如何实现登录日志记录的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
本文介绍的是利用 Laravel 事件系统实现登录日志记录的相关内容,分享出来给大家参考,下面来看看详细的介绍:
明确需求
记录一个登录日志,通常需要下列信息:
确立工具
明确完需求后,根据每个需求查找自己所需的工具吧。
- Request::getClientIp()
开工
采用 Laravel 的事件订阅系统来实现,需要实现一个登录事件和一个登录事件监听器。
生成事件和监听器
Laravel 命令行支持自动生成事件和监听器,在 App\Providers\EventServiceProvider 中添加需要实现的事件:
- protected $listen = [
- ...,
- //添加登录事件及对应监听器,一个事件可绑定多个监听器
- 'App\Events\LoginEvent' => [
- 'App\Listeners\LoginListener',
- ],
- ];
运行命令:
就会自动生成事件和监听器,已存在的事件和监听器不会发生改变。
- php artisan event:generate
登录事件 (Event)
回顾下需求,我们的登录事件需要的 5 点信息,在事件中需要记录这些信息,所以事件设计如下:
- namespace App\Events;
- use Illuminate\Broadcasting\Channel;
- use Illuminate\Queue\SerializesModels;
- use Illuminate\Broadcasting\PrivateChannel;
- use Illuminate\Foundation\Events\Dispatchable;
- use Illuminate\Broadcasting\InteractsWithSockets;
- use App\Models\User;
- use Jenssegers\Agent\Agent;
- 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('channel-default');
- }
- }
在事件中记录所需要的信息,并实现这些信息的 get 方法。
登录监听器 (Listener)
在监听器中,获取到事件传递过来的信息,把这些信息记录到数据库中,实现如下:
- namespace App\Listeners;
- use App\Events\LoginEvent;
- class LoginListener
- {
- // handle方法中处理事件
- public function handle(LoginEvent $event)
- {
- //获取事件中保存的信息
- $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($ip);
- $login_info['address'] = implode(' ', $addresses);
- // jenssegers/agent 的方法来提取agent信息
- $login_info['device'] = $agent->device(); //设备名称
- $browser = $agent->browser();
- $login_info['browser'] = $browser . ' ' . $agent->version($browser); //浏览器
- $platform = $agent->platform();
- $login_info['platform'] = $platform . ' ' . $agent->version($platform); //操作系统
- $login_info['language'] = implode(',', $agent->languages()); //语言
- //设备类型
- if ($agent->isTablet()) {
- // 平板
- $login_info['device_type'] = 'tablet';
- } else if ($agent->isMobile()) {
- // 便捷设备
- $login_info['device_type'] = 'mobile';
- } else if ($agent->isRobot()) {
- // 爬虫机器人
- $login_info['device_type'] = 'robot';
- $login_info['device'] = $agent->robot(); //机器人名称
- } else {
- // 桌面设备
- $login_info['device_type'] = 'desktop';
- }
- //插入到数据库
- DB::table('login_log')->insert($login_info);
- }
- }
这样,监听器就完成了,每次一触发登录事件,就会在数据库中添加一条登录信息。
触发事件
通过全局的
方法来触发事件,
- event()
方法的参数为事件实例:
- event()
- namespace App\Controllers;
- ...
- use App\Events\LoginEvent;
- use Jenssegers\Agent\Agent;
- class AuthControoler extends Controller
- {
- ...
- public function login(Request $request)
- {
- //登录实现
- ...
- //登录成功,触发事件
- event(new LoginEvent($this->guard()->user(), new Agent(), \Request::getClientIp(), time()));
- ...
- }
- }
队列化监听器
有时监听器会进行一些耗时操作,这时应该结合 Laravel 的队列系统将监听器进行队列化,前提是已经配置了队列并开启了队列处理器。
队列化非常简单,只需监听器实现 ShouldQueue 接口即可,即:
- namespace App\Listeners;
- ...
- use Illuminate\Contracts\Queue\ShouldQueue;
- class LoginListener implements ShouldQueue
- {
- /**
- * 失败重试次数
- * @var int
- */
- public $tries = 1;
- ...
- }
总结
Laravel 的事件系统实现起来还是非常优雅的,同一个事件可以很方便的添加各类监听器,且各个监听器之间互不干扰,解耦性非常强。加上队列系统,可以很方便的处理一些后续任务。
来源: http://www.phperz.com/article/17/0729/339795.html