亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用Laravel事件系統(tǒng)如何實(shí)現(xiàn)登錄日志的記錄詳解

 更新時(shí)間:2017年05月20日 11:23:18   作者:shrimp6  
這篇文章主要給大家介紹了利用Laravel事件系統(tǒng)如何實(shí)現(xiàn)登錄日志記錄的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。

本文介紹的是利用Laravel事件系統(tǒng)實(shí)現(xiàn)登錄日志記錄的相關(guān)內(nèi)容,分享出來(lái)給大家參考,下面來(lái)看看詳細(xì)的介紹:

明確需求

記錄一個(gè)登錄日志,通常需要下列信息:

  • 客戶端Agent信息
  • 客戶端IP地址
  • 訪問IP地點(diǎn)
  • 登錄時(shí)間
  • 登錄用戶信息

確立工具

明確完需求后,根據(jù)每個(gè)需求查找自己所需的工具吧。

  • 需求1 jenssegers/agent就可以滿足我們要求
  • 需求2 Laravel下直接Request::getClientIp()
  • 需求3 zhuzhichao/ip-location-zh這個(gè)包可以滿足要求
  • 需求4 time()
  • 需求5 登錄用戶模型

開工

采用Laravel的事件訂閱系統(tǒng)來(lái)實(shí)現(xiàn),需要實(shí)現(xiàn)一個(gè)登錄事件和一個(gè)登錄事件監(jiān)聽器。

生成事件和監(jiān)聽器

Laravel命令行支持自動(dòng)生成事件和監(jiān)聽器,在App\Providers\EventServiceProvider中添加需要實(shí)現(xiàn)的事件:

protected $listen = [ 
  ...,
  //添加登錄事件及對(duì)應(yīng)監(jiān)聽器,一個(gè)事件可綁定多個(gè)監(jiān)聽器
  'App\Events\LoginEvent' => [
  'App\Listeners\LoginListener',
 ],
];

運(yùn)行命令:php artisan event:generate就會(huì)自動(dòng)生成事件和監(jiān)聽器,已存在的事件和監(jiān)聽器不會(huì)發(fā)生改變。

登錄事件(Event)

回顧下需求,我們的登錄事件需要的5點(diǎn)信息,在事件中需要記錄這些信息,所以事件設(shè)計(jì)如下:

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對(duì)象
 */
 protected $agent;

 /**
 * @var string IP地址
 */
 protected $ip;

 /**
 * @var int 登錄時(shí)間戳
 */
 protected $timestamp;

 /**
 * 實(shí)例化事件時(shí)傳遞這些信息
 */
 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');
 }
} 

在事件中記錄所需要的信息,并實(shí)現(xiàn)這些信息的get方法。

登錄監(jiān)聽器(Listener)

在監(jiān)聽器中,獲取到事件傳遞過(guò)來(lái)的信息,把這些信息記錄到數(shù)據(jù)庫(kù)中,實(shí)現(xiàn)如下:

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 的方法來(lái)提取agent信息
 $login_info['device'] = $agent->device(); //設(shè)備名稱
 $browser = $agent->browser();  
 $login_info['browser'] = $browser . ' ' . $agent->version($browser); //瀏覽器
 $platform = $agent->platform();
 $login_info['platform'] = $platform . ' ' . $agent->version($platform); //操作系統(tǒng)
 $login_info['language'] = implode(',', $agent->languages()); //語(yǔ)言
 //設(shè)備類型
 if ($agent->isTablet()) {
  // 平板
  $login_info['device_type'] = 'tablet';
 } else if ($agent->isMobile()) {
  // 便捷設(shè)備
  $login_info['device_type'] = 'mobile';
 } else if ($agent->isRobot()) {
  // 爬蟲機(jī)器人
  $login_info['device_type'] = 'robot';
  $login_info['device'] = $agent->robot(); //機(jī)器人名稱
 } else {
  // 桌面設(shè)備
  $login_info['device_type'] = 'desktop';
 }

 //插入到數(shù)據(jù)庫(kù)
 DB::table('login_log')->insert($login_info);

 } 
}

這樣,監(jiān)聽器就完成了,每次一觸發(fā)登錄事件,就會(huì)在數(shù)據(jù)庫(kù)中添加一條登錄信息。

觸發(fā)事件

通過(guò)全局的event()方法來(lái)觸發(fā)事件,event()方法的參數(shù)為事件實(shí)例:

namespace App\Controllers; 
...
use App\Events\LoginEvent; 
use Jenssegers\Agent\Agent; 
class AuthControoler extends Controller 
{
 ...
 public function login(Request $request)
 {
 //登錄實(shí)現(xiàn)
 ...
 //登錄成功,觸發(fā)事件
 event(new LoginEvent($this->guard()->user(), new Agent(), \Request::getClientIp(), time()));
 ... 
 } 
} 

隊(duì)列化監(jiān)聽器

有時(shí)監(jiān)聽器會(huì)進(jìn)行一些耗時(shí)操作,這時(shí)應(yīng)該結(jié)合Laravel的隊(duì)列系統(tǒng)將監(jiān)聽器進(jìn)行隊(duì)列化,前提是已經(jīng)配置了隊(duì)列并開啟了隊(duì)列處理器。

隊(duì)列化非常簡(jiǎn)單,只需監(jiān)聽器實(shí)現(xiàn)ShouldQueue接口即可,即:

namespace App\Listeners; 
...
use Illuminate\Contracts\Queue\ShouldQueue; 
class LoginListener implements ShouldQueue 
{
 /**
 * 失敗重試次數(shù)
 * @var int
 */
 public $tries = 1;
 ...
} 

總結(jié)

Laravel的事件系統(tǒng)實(shí)現(xiàn)起來(lái)還是非常優(yōu)雅的,同一個(gè)事件可以很方便的添加各類監(jiān)聽器,且各個(gè)監(jiān)聽器之間互不干擾,解耦性非常強(qiáng)。加上隊(duì)列系統(tǒng),可以很方便的處理一些后續(xù)任務(wù)。

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

最新評(píng)論