[ Laravel 5.2 文檔 ] 服務 -- 事件

來源:互聯網
上載者:User

1、簡介

Laravel事件提供了簡單的觀察者模式實現,允許你訂閱和監聽應用中的事件。事件類別通常存放在 app/Events目錄,監聽器存放在 app/Listeners。

2、註冊事件/監聽器

Laravel 內建的 EventServiceProvider為事件註冊提供了方便之所。其中的 listen屬性包含了事件(鍵)和對應監聽器(值)數組。如果應用需要,你可以添加多個事件到該數組。例如,讓我們添加 PodcastWasPurchased事件:

/** * 事件監聽器映射 * * @var array */protected $listen = [    'App\Events\PodcastWasPurchased' => [        'App\Listeners\EmailPurchaseConfirmation',    ],];

2.1 建置事件/監聽器類

當然,手動為每個事件和監聽器建立檔案是很笨重的,取而代之地,我們可見簡單添加監聽器和事件到 EventServiceProvider然後使用 event:generate命令。該命令將會產生羅列在 EventServiceProvider中的所有事件和監聽器。當然,已存在的事件和監聽器不會被建立:

php artisan event:generate

2.2 手動註冊事件

一般我們需要將事件註冊到 EventServiceProvider的 $listen數組,此外,我們還可以使用 Event門面或者 Illuminate\Contracts\Events\Dispatcher契約的具體實作類別作為事件分發器手動註冊事件:

/** * Register any other events for your application. * * @param  \Illuminate\Contracts\Events\Dispatcher  $events * @return void */public function boot(DispatcherContract $events){    parent::boot($events);    $events->listen('event.name', function ($foo, $bar) {        //    });}

使用萬用字元作為事件監聽器

你還可以使用萬用字元*來註冊監聽器,從而允許你通過同一個監聽器捕獲多個事件。萬用字元監聽器接收整個事件數目據數組作為參數:

$events->listen('event.*', function (array $data) {    //});

3、定義事件

事件類別是一個處理與事件相關的簡單資料容器,例如,假設我們產生的 PodcastWasPurchased事件接收一個Eloquent ORM對象:

podcast = $podcast;    }}

正如你所看到的,該事件類別不包含任何特定邏輯,只是一個存放被購買的 Podcast對象的容器,如果事件對象被序列化的話,事件使用的 SerializesModelstrait 將會使用 PHP 的 serialize函數序列化所有 Eloquent 模型。

4、定義監聽器

接下來,讓我們看看我們的樣本事件的監聽器,事件監聽器在 handle方法中接收事件執行個體, event:generate命令將會自動在 handle方法中匯入合適的事件類別和類型提示事件。在 handle方法內,你可以執行任何需要的邏輯以響應事件。

podcast...    }}

你的事件監聽器還可以在構造器中類型提示任何需要的依賴,所有事件監聽器通過服務容器解析,所以依賴會自動注入:

use Illuminate\Contracts\Mail\Mailer;public function __construct(Mailer $mailer){    $this->mailer = $mailer;}

停止事件繼續往下傳播

有時候,你希望停止事件被傳播到其它監聽器,你可以通過從監聽器的 handle方法中返回 false來實現。

事件監聽器隊列

需要將事件監聽器放到隊列?沒有比這更簡單的了,只需要讓監聽器類實現 ShouldQueue介面即可,通過 Artisan 命令 event:generate產生的監聽器類已經將介面匯入當前命名空間,所有你可以立即拿來使用:

    

就是這麼簡單,當監聽器被事件調用,將會使用 Laravel 的隊列系統通過隊列分發器自動隊列化。如果通過隊列執行監聽器的時候沒有拋出任何異常,隊列任務在執行完成後被自動刪除。

手動訪問隊列

如果你需要手動訪問底層隊列任務的 delete和 release方法,在產生的監聽器中預設匯入的 Illuminate\Queue\InteractsWithQueuetrait 提供了訪問這兩個方法的許可權:

release(30);        }    }}

5、觸發事件

要觸發一個事件,可以使用 Event門面,傳遞一個事件執行個體到 fire方法, fire方法會分發事件到所有監聽器:

    

此外,你還可以使用全域的輔助函數 event來觸發事件:

event(new PodcastWasPurchased($podcast));

6、 廣播事件

在很多現代 Web 應用程式中,Web 通訊端被用於實現即時更新的使用者介面。當一些資料在伺服器上被更新,通常一條訊息通過 websocket 串連被發送給用戶端處理。

為協助你構建這樣的應用,Laravel 讓通過 websocket 串連廣播事件變得簡單。廣播 Laravel 事件允許你在服務端和用戶端 JavaScript 架構之間共用同一事件名。

6.1 配置

所有的事件廣播配置選項都存放在 config/broadcasting.php設定檔中。Laravel 支援多種廣播驅動: Pusher、Redis以及一個服務於本地開發和調試的日誌驅動。每一個驅動都有一個配置樣本。

廣播預備知識

事件廣播需要以下兩個依賴:

  • Pusher: pusher/pusher-php-server ~2.0
  • Redis: predis/predis ~1.0

隊列預備知識

在開始介紹廣播事件之前,還需要配置並運行一個隊列監聽器。所有事件廣播都通過隊列任務來完成以便應用的回應時間不受影響。

6.2 將事件標記為廣播

要告訴 Laravel 給定事件應該被廣播,需要在事件類別上實現 Illuminate\Contracts\Broadcasting\ShouldBroadcast介面。 ShouldBroadcast介面要求你實現一個方法: broadcastOn。該方法應該返回事件廣播“頻道”名稱數組:

user = $user;    }    /**     * 擷取事件廣播頻道     *     * @return array     */    public function broadcastOn()    {        return ['user.'.$this->user->id];    }}

然後,你只需要和正常一樣觸發該事件,事件被觸發後,一個隊列任務將通過指定廣播驅動自動廣播該事件。

6.3 廣播資料

如果某個事件被廣播,其所有的 public屬性都會按照事件裝載自動序列化和廣播,從而允許你從 JavaScript 中訪問所有 public資料,因此,舉個例子,如果你的事件有一個單獨的包含 Eloquent 模型的 $user屬性,廣播負載定義如下:

{    "user": {        "id": 1,        "name": "Jonathan Banks"        ...    }}

然而,如果你希望對廣播負載有更加細粒度的控制,可以添加 broadcastWith方法到事件,該方法應該返回你想要通過事件廣播的數組資料:

/** * 擷取廣播資料 * * @return array */public function broadcastWith(){    return ['user' => $this->user->id];}

6.4 自訂事件廣播

自訂事件名

預設情況下,廣播事件名就是事件類別名,因此,如果事件的類名是 App\Events\ServerCreated,對應的廣播事件名就是 App\Events\ServerCreated,你可以通過事件類別上的 broadcastAs方法自訂廣播事件名:

/** * 擷取廣播事件名稱 * * @return string */public function broadcastAs(){    return 'app.server-created';}

自訂隊列

預設情況下,每個被廣播的事件都位於設定檔 queue.php中定義的預設隊列串連中的預設隊列中,你可以通過事件類別的 onQueue方法自訂廣播事件的隊列名稱。該方法會返回你期望使用的隊列名:

/** * 設定事件所在隊列的名稱 * * @return string */public function onQueue(){    return 'your-queue-name';}

6.5 消費事件廣播

Pusher

你可以通過 Pusher 的 JavaScript SDK 方便地使用 Pusher驅動消費事件廣播。例如,讓我們從之前的例子中消費 App\Events\ServerCreated事件:

this.pusher = new Pusher('pusher-key');this.pusherChannel = this.pusher.subscribe('user.' + USER_ID);this.pusherChannel.bind('App\\Events\\ServerCreated', function(message) {    console.log(message.user);});

Redis

如果你在使用 Redis 廣播,你將需要編寫自己的 Redis pub/sub 消費者來接收訊息並使用自己選擇的 websocket 技術將其進行廣播。例如,你可以選擇使用 Node 編寫的流行的 Socket.io庫。

使用 Node 庫 socket.io和 ioredis,你可以快速編寫事件廣播發布所有廣播事件:

var app = require('http').createServer(handler);var io = require('socket.io')(app);var Redis = require('ioredis');var redis = new Redis();app.listen(6001, function() {    console.log('Server is running!');});function handler(req, res) {    res.writeHead(200);    res.end('');}io.on('connection', function(socket) {    //});redis.psubscribe('*', function(err, count) {    //});redis.on('pmessage', function(subscribed, channel, message) {    message = JSON.parse(message);    io.emit(channel + ':' + message.event, message.data);});

7、事件訂閱者

事件訂閱者是指那些在類本身中訂閱到多個事件的類,從而允許你在單個類中定義一些事件處理器。訂閱者應該定義一個 subscribe方法,該方法中傳入一個事件分發器執行個體:

listen(            'App\Events\UserLoggedIn',            'App\Listeners\UserEventListener@onUserLogin'        );        $events->listen(            'App\Events\UserLoggedOut',            'App\Listeners\UserEventListener@onUserLogout'        );    }}

註冊一個事件訂閱者

訂閱者被定義後,可以通過事件分發器進行註冊,你可以使用 EventServiceProvider上的 $subcribe屬性來註冊訂閱者。例如,讓我們添加 UserEventListener:

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.