除了 Email 以外 Laravel 也有著各種各樣的通知功能,這些功能整合在 Notifcation
模組中。 Notification
預設包含信件、簡訊(使用 Vonage
)以及 Slack 通知,需要更多能的話要引入第三方套件,社群很貼心的整理了可用的套件清單。
如果要使用通知功能,首先要在模型中加上 Notifiable
屬性,Laravel 預設建立的 User
模型就已經有使用。
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; // Notifiable 屬性
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable; // 引用屬性
//...
}
有了 Notifiable
屬性,模型的實例就可以使用 notify
功能發送通知。
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
notify
需要 Illuminate\Notifications\Notification
的實例作為參數,可以用指令產生繼承 Illuminate\Notifications\Notification
的類別,預設放在 app/Notifications/
目錄下。
sail artisan make:notification VerifyNotification
app/Notifications/VerifyNotification.php
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class VerifyNotification extends Notification
{
use Queueable;
//...
}
產生的 Notification 預設帶有 Queueable
屬性,可以存入 Laravel 的佇列中易步執行,這個之後介紹。
via
是 Notification 類別中用於定義這則通知要經由哪些 channel
進行發送,也就是通知的管道。一則通知可以同時經由複數管道發送。
public function via($notifiable)
{
return ['mail','database'];
}
當定義了管道,要確保有對應該管道的方法定義發送通知的方法,例如 mail 管道需要定義 toMail
方法。
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
上面函式都帶有 $notifiable
參數,這個是指被傳送通知的對象,會是帶有 Notifiable
屬性的 Model ,像是 User。
use App\Notifications\VerifyNotification;
$user->notify(new VerifyNotification());
像這樣發送 VerifyNotification
通知的話, VerifyNotification
中的函式所帶入的 $notifiable
就會是 $user
。
各個寄送管道對應的方法有各自必須回傳的類別,以 toMail
來說就需要回傳 Illuminate\Mail\Mailable
的實例,所以也可以用我們自製的信件類別。
public function toMail($notifiable)
{
return new CustomVerifyMail;
}
其他第三方套件也都有類似的函式,像是 AWS SNS 需要定義 toSns
函式。
database
通知管道用於將通知紀錄於資料庫中,對應的函式用 toArray
或 toDatabase
都可以。
public function toArray($notifiable)
{
return [
'invoice_id' => $this->invoice->id,
'amount' => $this->invoice->amount,
];
}
不過在使用之前記得先建好資料表單。
php artisan notifications:table
php artisan migrate
除了預設的通知管道像 mail
,database
外,也可以自定義管道,各套件也都有定義。
例如 AWS SNS
的 SnsChannel
。
<?php
use NotificationChannels\AwsSns\SnsChannel;
use NotificationChannels\AwsSns\SnsMessage;
use Illuminate\Notifications\Notification;
class AccountApproved extends Notification
{
public function via($notifiable)
{
return [SnsChannel::class];
}
//...
}
自己撰寫 Channel 的話,要包含有 send
函式。
<?php
namespace App\Channels;
use Illuminate\Notifications\Notification;
class VoiceChannel
{
public function send($notifiable, Notification $notification)
{
$message = $notification->toVoice($notifiable);
}
}
send
需要兩個參數,第一個 $$notifiable
跟前面一樣是傳送的對象,也是經由 Notification
類別底下的 via
傳入的。 另一個 $notification
就是 Notification
物件本身,所以可以在 Notification
底下定義傳送的方式,就像 toMail
,toSns
等,然後在這裡使用。