?
有時(shí)候當(dāng)我們單純的看 Laravel
手冊(cè)的時(shí)候會(huì)有一些疑惑,比如說系統(tǒng)服務(wù)下的授權(quán)和事件,這些功能服務(wù)的應(yīng)用場景是什么,其實(shí)如果沒有經(jīng)歷過一定的開發(fā)經(jīng)驗(yàn)有這些疑惑是很正常的事情,但是當(dāng)我們?cè)诠ぷ髦卸嗉铀伎紩?huì)發(fā)現(xiàn)有時(shí)候這些服務(wù)其實(shí)我們一直都見過。下面就事件、事件監(jiān)聽舉一個(gè)很簡單的例子你就會(huì)發(fā)現(xiàn)。
? 這個(gè)例子是關(guān)于文章的瀏覽數(shù)的實(shí)現(xiàn),當(dāng)用戶查看文章的時(shí)候文章的瀏覽數(shù)會(huì)增加1,用戶查看文章就是一個(gè)事件,有了事件,就需要一個(gè)事件監(jiān)聽器,對(duì)監(jiān)聽的事件發(fā)生后執(zhí)行相應(yīng)的操作(文章瀏覽數(shù)加1),其實(shí)這種監(jiān)聽機(jī)制在 Laravel
中是通過觀察者模式實(shí)現(xiàn)的.
首先我們需要在 app/PRoviders/
目錄下的EventServiceProvider.php
中注冊(cè)事件監(jiān)聽器映射關(guān)系,如下:
protected $listen = [ 'App/Events/BlogView' => [ 'App/Listeners/BlogViewListener', ], ];
然后項(xiàng)目根目錄下執(zhí)行如下命令
php artisan event:generate
該命令完成后,會(huì)分別自動(dòng)在 app/Events
和app/Listensers
目錄下生成 BlogView.php
和BlogViewListener.php
文件。
<?phpnamespace App/Events;use App/Events/Event;use App/Post;use Illuminate/Queue/SerializesModels;use Illuminate/Contracts/Broadcasting/ShouldBroadcast;class BlogView extends Event{ use SerializesModels; /** * Create a new event instance. * * @return void */ public function __construct(Post $post) { $this->post = $post; } /** * Get the channels the event should be broadcast on. * * @return array */ public function broadcastOn() { return []; }}
其實(shí)看到這些你會(huì)發(fā)現(xiàn)該事件類只是注入了一個(gè) Post
實(shí)例罷了,并沒有包含多余的邏輯。
事件監(jiān)聽器在handle
方法中接收事件實(shí)例,event:generate命令將會(huì)自動(dòng)在handle方法中導(dǎo)入合適的事件類和類型提示事件。在handle
方法內(nèi),你可以執(zhí)行任何需要的邏輯以響應(yīng)事件,我們的代碼實(shí)現(xiàn)如下:
<?phpnamespace App/Listeners;use App/Events/BlogView;use Illuminate/Queue/InteractsWithQueue;use Illuminate/Contracts/Queue/ShouldQueue;use Illuminate/session/Store;class BlogViewListener{ protected $session; /** * Create the event listener. * * @return void */ public function __construct(Store $session) { $this->session = $session; } /** * Handle the event. * * @param BlogView $event * @return void */ public function handle(BlogView $event) { $post = $event->post; //先進(jìn)行判斷是否已經(jīng)查看過 if (!$this->hasViewedBlog($post)) { //保存到數(shù)據(jù)庫 $post->view_cache = $post->view_cache + 1; $post->save(); //看過之后將保存到 Session $this->storeViewedBlog($post); } } protected function hasViewedBlog($post) { return array_key_exists($post->id, $this->getViewedBlogs()); } protected function getViewedBlogs() { return $this->session->get('viewed_Blogs', []); } protected function storeViewedBlog($post) { $key = 'viewed_Blogs.'.$post->id; $this->session->put($key, time()); }}
注釋中也已經(jīng)說明了一些邏輯。
事件和事件監(jiān)聽完成后,我們要做的就是實(shí)現(xiàn)整個(gè)監(jiān)聽,即觸發(fā)用戶打開文章事件在此我們使用和 Event
提供的 fire
方法,如下:
<?phpnamespace App/Http/Controllers;use Illuminate/Http/Request;use App/Post;use Illuminate/Support/Facades/Event;use App/Http/Requests;use App/Events/BlogView;use App/Http/Controllers/Controller;class BlogController extends Controller{ public function showPost($slug) { $post = Post::whereSlug($slug)->firstOrFail(); Event::fire(new BlogView($post)); return view('home.blog.content')->withPost($post); }}
現(xiàn)在打開頁面發(fā)現(xiàn)數(shù)據(jù)庫中的`view_cache已經(jīng)正常加1了,這樣整個(gè)就完成了。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注