Laravel 中的事件監聽

你就是隻蠢狗發表於2017-10-29

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

這個例子是關於文章的瀏覽數的實現,當使用者檢視文章的時候文章的瀏覽數會增加1,使用者檢視文章就是一個事件,有了事件,就需要一個事件監聽器,對監聽的事件發生後執行相應的操作(文章瀏覽數加1),其實這種監聽機制在 Laravel 中是透過觀察者模式實現的

1.註冊事件以及監聽器

  • 首先我們需要在 app/Providers/目錄下的EventServiceProvider.php中註冊事件監聽器對映關係,如下:
protected $listen = [
        'App\Events\BlogView' => [
            'App\Listeners\BlogViewListener',
        ],
    ];
  • 然後專案根目錄下執行如下命令
    php artisan event:generate
  • 該命令完成後,會分別自動在 app/Events和app/Listensers目錄下生成 BlogView.php和BlogViewListener.php檔案

    2.定義事件

<?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 [];
    }
}

3.定義監聽器

事件監聽器在handle方法中接收事件例項,event:generate命令將會自動在handle方法中匯入合適的事件類和型別提示事件。在handle方法內,你可以執行任何需要的邏輯以響應事件,我們的程式碼實現如下:

<?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());
    }

}

4.觸發事件

事件和事件監聽完成後,我們要做的就是實現整個監聽,即觸發使用者開啟文章事件在此我們使用和 Event提供的 fire方法,如下:

<?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);
    }

}

轉載自storeword

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章