Laravel 5.1 事件、事件監聽的簡單應用

bVqBce

​ 有時候當咱們單純的看 Laravel 手冊的時候會有一些疑惑,好比說系統服務下的受權和事件,這些功能服務的應用場景是什麼,其實若是沒有經歷過必定的開發經驗有這些疑惑是很正常的事情,可是當咱們在工做中多加思考會發現有時候這些服務其實咱們一直都見過。下面就事件、事件監聽舉一個很簡單的例子你就會發現。php

​ 這個例子是關於文章的瀏覽數的實現,當用戶查看文章的時候文章的瀏覽數會增長1,用戶查看文章就是一個事件,有了事件,就須要一個事件監聽器,對監聽的事件發生後執行相應的操做(文章瀏覽數加1),其實這種監聽機制在 Laravel 中是經過觀察者模式實現的.laravel

註冊事件以及監聽器

首先咱們須要在 app/Providers/目錄下的EventServiceProvider.php中註冊事件監聽器映射關係,以下:數據庫

protected $listen = [
        'App\Events\BlogView' => [
            'App\Listeners\BlogViewListener',
        ],
    ];

而後項目根目錄下執行以下命令session

php artisan event:generate

該命令完成後,會分別自動在 app/Eventsapp/Listensers目錄下生成 BlogView.phpBlogViewListener.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

相關文章
相關標籤/搜索