laravel 事件/監(jiān)聽器實(shí)例代碼
導(dǎo)語
上一篇文章實(shí)現(xiàn)了記錄用戶訪問,設(shè)計(jì)上是有缺陷的,代碼緊耦合在中間件。如果后續(xù)修改需求,不僅記錄 ip、城市,還需要記錄數(shù)據(jù)到新的數(shù)據(jù)表,或者需要進(jìn)行其它統(tǒng)計(jì),那么不停的增加、修改代碼是不合理的。這個(gè)時(shí)候可以使用 Laravel 的事件/監(jiān)聽器進(jìn)行處理。代碼可查看 GitHub。
事件/監(jiān)聽器
Laravel 事件提供了簡單的觀察者模式實(shí)現(xiàn),允許你訂閱和監(jiān)聽?wèi)?yīng)用中的事件。
觀察者模式有時(shí)也被稱作發(fā)布/訂閱模式,該模式用于為對象實(shí)現(xiàn)發(fā)布/訂閱功能:一旦主體對象狀態(tài)發(fā)生改變,與之關(guān)聯(lián)的觀察者對象會收到通知,并進(jìn)行相應(yīng)操作。
以上是事件/監(jiān)聽器、觀察者模式的簡要說明。結(jié)合這次的需求理解,當(dāng)觸發(fā)用戶訪問事件,它的觀察者進(jìn)行處理。觀察者可以是多個(gè),本例僅做入庫操作。
創(chuàng)建事件/監(jiān)聽器
在 app/Providers/EventServiceProvider.php 文件中添加事件/監(jiān)聽器,如下
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ Registered::class => [ SendEmailVerificationNotification::class, ], 'App\Events\UserBrowse' => [ 'App\Listeners\CreateBrowseLog', // 其它監(jiān)聽器 ], ];
添加好之后,執(zhí)行 php artisan event:generate,會自動創(chuàng)建對應(yīng)的事件/監(jiān)聽器。分別創(chuàng)建了 app/Events/UserBrowse.php 和 app/Listeners/CreateBrowseLog.php 兩個(gè)文件。
實(shí)現(xiàn)代碼
把目光聚集到事件 app/Events/UserBrowse.php 文件,這里需要接收數(shù)據(jù)以便后續(xù)處理,代碼如下
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; }
然后是監(jiān)聽器 app/Listeners/CreateBrowseLog.php,這里要做的是,將事件中接收到的數(shù)據(jù)進(jìn)行入庫操作,代碼如下
/** * 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(); }
分發(fā)事件
最后就是分發(fā)事件,修改 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) { // 使用事件/監(jiān)聽器入庫 event(new UserBrowse($request->getClientIp(), $request->path(), get_city_by_ip(false, 'null'))); return $next($request); }
測試之后是沒有問題的。
結(jié)語
這次所做的修改,感官上來看,就是將入庫操作從中間件轉(zhuǎn)移到監(jiān)聽器中,實(shí)際上的意義遠(yuǎn)不止于此。例如同一個(gè)事件,可以分發(fā)在不同的地方;事件添加了需求,只需要在添加一個(gè)監(jiān)聽器即可;監(jiān)聽器中也可以使用隊(duì)列等等。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
php實(shí)現(xiàn)中文轉(zhuǎn)數(shù)字
這里給大家分享的是一則使用php實(shí)現(xiàn)的中文轉(zhuǎn)數(shù)字的代碼,非常智能,也很完美,有需要的小伙伴可以參考下。2016-02-02PHP中__set()實(shí)例用法和基礎(chǔ)講解
在本篇文章里小編給大家整理了關(guān)于HP中__set()實(shí)例用法和基礎(chǔ)講解,對此有需要的朋友們可以學(xué)習(xí)參考下。2019-07-07PHP循環(huán)結(jié)構(gòu)實(shí)例講解
這篇文章主要介紹了PHP循環(huán)結(jié)構(gòu)實(shí)例講解,需要的朋友可以參考下2014-02-02ThinkPHP提示錯(cuò)誤Fatal error: Allowed memory size的解決方法
這篇文章主要介紹了ThinkPHP提示錯(cuò)誤Fatal error: Allowed memory size的解決方法,分析了該錯(cuò)誤的原因與具體的解決方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02centos+php+coreseek+sphinx+mysql之一coreseek安裝篇
這篇文章主要介紹了centos+php+coreseek+sphinx+mysql之一coreseek安裝篇的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-10-10PHP setTime 設(shè)置當(dāng)前時(shí)間的代碼
在用JAVA中有個(gè) Calendar 可設(shè)置當(dāng)前時(shí)間,在PHP中找了半天,終于給我找到了這個(gè)函數(shù),嘎嘎2012-08-08