Laravel - Digging Deeper - Events (官方文件原子化翻譯筆記)

# 前言

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。



# Registering Events & Listeners

以下位於 EventServiceProvider 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected $listen = [
    'App\Events\OrderShipped' => [
    'App\Listeners\SendShipmentNotification',
    ],
    ];
  • Answer:
    在 EventServiceProvider 的 $listen property 中
    註冊一個 Listener SendShipmentNotification 監聽 OrderShipped event

# Generating Events & Listeners

Laravel 中, 我先在 EventServiceProvider 的 $listen protected property 定義好 event 跟 listener 之後, 怎麼使用 CLI 讓定義好的 event 跟 listener 自動產生?
php artisan event:generate

# Manually Registering Events

Laravel 中, 如果我想要定義 closure based event, 我可以在哪一個檔案中定義?

EventServiceProvider

Laravel 中, 如果我想要定義 closure based event, 我可以在 EventServiceProvider 中的 哪一個 method 中定義?

boot method

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    public function boot()
    {
    parent::boot();

    Event::listen('event.name', function ($foo, $bar) {
    //
    });
    }
  • Answer:
    在 EventServiceProvider 的 boot method 定義 closure based event, 第一個 argument 為該 event name, closure 內為 trigger event 時要做的事, 相當於定義於 Listener 中的邏輯

# Wild Event Listeners

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Event::listen('registered.*', function ($eventName, array $data) {
    //
    });
  • Answer:
    監聽所有 registered. 開頭的 event
以下的 Laravel example code 的意思是?
  • Example:
    <?php
    Event::listen('event.*', function ($eventName, array $data) {
    //
    });
  • Answer:
    監聽 wildcard event, 第一個 argument 為 event name, 第二個為該 event 的 data

# Event Discovery

Laravel Event 中, Event Discovery 的規則, 會 scan 哪一個資料夾中的 Listeners?

Listeners directory

Laravel Event 中, Event Discovery 的規則, 假設以下的 Listener 為我 scan 到的 Listener, Laravel 會將這個 Listener 註冊給哪一個 event?
  • Example:
    <?php
    use App\Events\PodcastProcessed;

    class SendPodcastProcessedNotification
    {
    public function handle(PodcastProcessed $event)
    {
    //
    }
    }
  • Answer:

PodcastProcessed event

Laravel Event 中, Event Discovery 的規則, 預設是關閉的還是打開的?

關閉的

以下的 Laravel example code 的意思是?
  • Example:
    <?php
    public function shouldDiscoverEvents()
    {
    return true;
    }
  • Answer:
    Laravel 預設關閉 Event Discovery, 就是會根據 convention 將 listener 註冊給 listener handle method 中 type hint 的 event class
    若要開啟, 可在 EventServiceProvider 的 shouldDiscoverEvents() 中開啟
以下位於 EventServiceProvider 的 Laravel example code 的意思是?
  • Example:
    <?php
    protected function discoverEventsWithin()
    {
    return [
    $this->app->path('Listeners'),
    ];
    }
  • Answer:
    若有開啟 Event Discovery, 預設會掃描 ‘app/Listeners’ 資料夾內的 events, 若要變更資料夾位置, 可在 discoverEventsWithin() 中定義
Laravel production 環境中, 我們可能不想要框架在每一個 request 都去 scan 所有的 listeners, 可以使用哪一個 CLI 來將 events 以及 listeners cache 住?
php artisan event:cache
Laravel production 環境中, 我們可能不想要框架在每一個 request 都去 scan 所有的 listeners, 所以使用 CLI 來 cache events 以及 listeners, 如果我要將 cache 拿掉, 可以使用哪一個 CLI?
php artisan event:clear
Laravel 中, 如果我想要使用 CLI 來顯示所有 events 以及 listeners 的對應關係, 可以使用哪一個 CLI?
php artisan event:list


# Defining Events

Laravel Event 中, 會寫到邏輯嗎?

不會哦



# Defining Listeners

# Stopping The Propagation Of An Event

Laravel 中, 如果我想要停止某個 listener 對某個 event 的傳播, 那我可以在該 listener 的 handle method 中回傳什麼?

false



# Queued Event Listeners

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    //
    }
  • Answer:
    將 listener class implement ShouldQueue interface, 當觸發該 listener 時, 該 job 會被 queue

# Customizing The Queue Connection & Queue Name

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    public $connection = 'sqs';
    }
  • Answer:
    在 listener class 當中指定 connection 為 ‘sqs’
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    public $queue = 'listeners';
    }
  • Answer:
    在 listener class 中使用 $queue 指定該 listener 使用的 queue
以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    public $delay = 60;
    }
  • Answer:
    在 listener class 中, 使用 $delay 定義該 job 在被 release 回 queue 後, 至少須等待 60 秒才可在被 worker pick up 執行
    Laravel 8 又叫做 backoff

# Conditionally Queueing Listeners

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderPlaced;
    use Illuminate\Contracts\Queue\ShouldQueue;

    class RewardGiftCard implements ShouldQueue
    {
    public function handle(OrderPlaced $event)
    {
    //
    }

    public function shouldQueue(OrderPlaced $event)
    {
    return $event->order->subtotal >= 5000;
    }
    }
  • Answer:
    當 Order model 的 subtotal attribute 大於等於 5000 時, queue 該 listener

# Manually Accessing The Queue

Laravel Events & Listeners 中, 如果我想要在程式碼中可以手動的 release 或 delete 該 listener job, 那我可以在該 Listener 中使用哪一個 trait?

InteractsWithQueue trait

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Queue\InteractsWithQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    use InteractsWithQueue;

    public function handle(OrderShipped $event)
    {
    if (true) {
    $this->release(30);
    }
    }
    }
  • Answer:
    若要在 listener job 中可對 job 做 release 或 delete 操作, 需 use InteractsWithQueue

# Handling Failed Jobs

Laravel Event & Listener 中, 如果我想要在 Listener 失敗後做相對應的邏輯, 那我可以在 Listener 當中定義哪一個 method?

failed method

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    use App\Events\OrderShipped;
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Queue\InteractsWithQueue;

    class SendShipmentNotification implements ShouldQueue
    {
    use InteractsWithQueue;

    public function handle(OrderShipped $event)
    {
    //
    }

    public function failed(OrderShipped $event, $exception)
    {
    //
    }
    }
  • Answer:
    在 listener class 內定義 failed(), 當 listener job failed 時, 執行 failed() 內的邏輯


# Dispatching Events

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Http\Controllers;

    use App\Events\OrderShipped;
    use App\Http\Controllers\Controller;
    use App\Order;

    class OrderController extends Controller
    {
    public function ship($orderId)
    {
    $order = Order::findOrFail($orderId);

    // Order shipment logic...

    event(new OrderShipped($order));
    }
    }
  • Answer:
    觸發 OrderShipped event


# Event Subscribers

# Writing Event Subscribers

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Listeners;

    class UserEventSubscriber
    {
    public function handleUserLogin($event) {}

    public function handleUserLogout($event) {}

    public function subscribe($events)
    {
    $events->listen(
    'Illuminate\Auth\Events\Login',
    'App\Listeners\UserEventSubscriber@handleUserLogin'
    );

    $events->listen(
    'Illuminate\Auth\Events\Logout',
    'App\Listeners\UserEventSubscriber@handleUserLogout'
    );
    }
    }
  • Answer:
    在 EventSubscriber 的 subscribe method 中定義 event 以及 listener, 然後直接在此 class 中定義 listener 邏輯

# Registering Event Subscribers

以下的 Laravel example code 的意思是?
  • Example:
    <?php

    namespace App\Providers;

    use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

    class EventServiceProvider extends ServiceProvider
    {
    protected $listen = [
    //
    ];

    protected $subscribe = [
    'App\Listeners\UserEventSubscriber',
    ];
    }
  • Answer:
    使用 EventServiceProvider 的 $subscribe property 來註冊事先已建立的 UserEventSubscriber’, EventSubscriber 可以在一個 class 中定義多個 listener 邏輯, 並 map 與之相對應的 event, 這樣就不需要建立多個 class, 每個 class 只定義一個 listener
<未完成> Kubernetes - Volumes Laravel - The Basics - Logging (官方文件原子化翻譯筆記)

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×