有時候當咱們單純的看 Laravel
手冊的時候會有一些疑惑,好比說系統服務下的受權和事件,這些功能服務的應用場景是什麼,其實若是沒有經歷過必定的開發經驗有這些疑惑是很正常的事情,可是當咱們在工做中多加思考會發現有時候這些服務其實咱們一直都見過。下面就事件、事件監聽舉一個很簡單的例子你就會發現。php
這個例子是關於文章的瀏覽數的實現,當用戶查看文章的時候文章的瀏覽數會增長1,用戶查看文章就是一個事件,有了事件,就須要一個事件監聽器,對監聽的事件發生後執行相應的操做(文章瀏覽數加1),其實這種監聽機制在 Laravel
中是經過觀察者模式實現的.laravel
首先咱們須要在 app/Providers/
目錄下的EventServiceProvider.php
中註冊事件監聽器映射關係,以下:數據庫
protected $listen = [ 'App\Events\BlogView' => [ 'App\Listeners\BlogViewListener', ], ];
而後項目根目錄下執行以下命令session
php artisan event:generate
該命令完成後,會分別自動在 app/Events
和app/Listensers
目錄下生成 BlogView.php
和BlogViewListener.php
文件。app
<?php namespace 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 []; } }
其實看到這些你會發現該事件類只是注入了一個 Post
實例罷了,並無包含多餘的邏輯。ide
事件監聽器在handle
方法中接收事件實例,event:generate命令將會自動在handle方法中導入合適的事件類和類型提示事件。在handle
方法內,你能夠執行任何須要的邏輯以響應事件,咱們的代碼實現以下:post
<?php namespace 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; //先進行判斷是否已經查看過 if (!$this->hasViewedBlog($post)) { //保存到數據庫 $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()); } }
註釋中也已經說明了一些邏輯。this
事件和事件監聽完成後,咱們要作的就是實現整個監聽,即觸發用戶打開文章事件在此咱們使用和 Event
提供的 fire
方法,以下:spa
<?php namespace 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); } }
如今打開頁面發現數據庫中的 view_cache
已經正常加1了,這樣整個就完成了。code