前言
在《L02 Laravel 教程 - Web 開發實戰進階 ( Laravel 8.x )》的3.7節——認證後的提示
中就用到了事件監聽。
雖然laravel提供了一套成熟的註冊登入的功能。在註冊時,需要使用者郵件認證,但是當使用者點選認證郵件中的連結後,就註冊成功並跳轉到主頁。但是問題是沒有任何反饋,這樣的體驗很不好。郵件認證的邏輯在vendor/laravel/ui/auth-backend/VerifiesEmails.php
中,理論上只要修改驗證成功後的邏輯就好了,但是課程中提到修改vendor/laravel/ui/auth-backend/VerifiesEmails.php
檔案是不可取的。那該怎麼辦呢?就涉及到今天這篇部落格的主題了——事件監聽。通過對Verified
事件進行監聽,就可以輕鬆的解決這個問題。
兩個例子:
教程中並沒有對事件監聽進行展開,文件寫的也很抽象,還是通過兩個例子來認識事件監聽吧:
1. 實現文章瀏覽的計數。
場景:使用者瀏覽文章後,瀏覽數+1。
具體實現:
1.1 註冊事件和監聽器
在App\Providers\EventServiceProvider
中註冊所有的事件監聽者。具體如下:
protected $listen = [
'App\Events\BlogView' => [
'App\Listeners\BlogViewListener',
],
];
// 鍵為事件,值為監聽器。
1.2 生成事件和監聽器
在命令列中執行php artisan event:generate
,此命令將生成 EventServiceProvider 中列出的、尚不存在的任何事件或監聽器。
1.2.1 自動生成的事件檔案app/Events/BlogView.php
如下:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class BlogView
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
1.2.2 自動生成的監聽器檔案app/Listeners/BlogViewListener.php
如下:
<?php
namespace App\Listeners;
use App\Events\BlogView;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class BlogViewListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param \App\Events\BlogView $event
* @return void
*/
public function handle(BlogView $event)
{
//
}
}
1.3 定義事件:考慮到要處理帖子模型,修改BlogView.php的構造器,在例項化的時候就將post
例項賦值給post
屬性。(對事件的處理視具體情況而定)
<?php
namespace App\Events;
use App\Models\Post;
...
class BlogView
{
...
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
...
}
1.4 定義監聽器:事件發生時,瀏覽數+1。
<?php
namespace App\Listeners;
...
class BlogViewListener
{
...
public function handle(BlogView $event)
{
$post = $event->post;
dd('瀏覽數+1!');
}
}
1.5 觸發事件:當使用者檢視文章的時候就觸發。
<?php
namespace App\Http\Controllers;
use App\Models\Post;
// 注意這裡需要引入BlogView類。
use App\Events\BlogView;
...
class PostController extends Controller
{
...
public function show(){
$post = Post::find(1);
// 觸發事件
event(new BlogView($post));
return view('post.show');
}
}
1.6 結果:
2. 物流發貨後,發簡訊通知使用者。
前輩的這篇部落格——記錄下學習筆記(Laravel 中的事件監聽)寫的已經很清楚了,就不再贅言。
什麼是事件?
在第一個例子中,事件是檢視文章。
在第一個例子中,事件是物流發貨。
感覺事件可以是任何動作。
什麼是監聽器?
不太好下定義,但是可以通過監聽器的功能來理解什麼是監聽器。當監聽器用於監聽事件,事件一旦觸發,就執行相應的邏輯。
具體步驟
1. 註冊事件和監聽器。
2. 生成事件和監聽器。
3. 定義事件和監聽器。
4. 觸發事件。
注意事項
1. 如果希望再某個類的某個動作中觸發事件,需要在該類中引入事件類。例如:在第一個例子中,是在PostController
類的show
動作中觸發了事件,所以需要在PostController
類中引入BlogView
事件類:
<?php
// 注意這裡需要引入BlogView類。
use App\Events\BlogView;
...
class PostController extends Controller
{
...
}
2. 一個事件可以由多個監聽器監聽。在第二個例子中,物流發貨後,我希望可以同時傳送簡訊和微信通知使用者,可以通過定義兩個監聽器實現:
protected $listen = [
'App\Events\OrderEvent' => [
'App\Listeners\sendModel',
'App\Listeners\sendPhone',
]
];
感謝laravel-china社群
laravel框架很多功能都封裝好了,所以在學課程的3.7節時,就感覺事件監聽不難。但是我去看文件的時候,又看的迷迷糊糊的。不過幸好有很多前輩在這個社群寫過很多優秀的,關於事件監聽的部落格,所以我很容易就收集到了例子。在這些例子中才對事件監聽有一點感覺,才知道該怎麼用。
參考:
3. 文件
本作品採用《CC 協議》,轉載必須註明作者和本文連結