这里我们使用 Laravel 开发一个站内信的功能。
文档 - 消息通知

编辑 User 模型

使用 Notifiable Trait

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable; // 使用 Notifiable Trait
}

这个 trait,它包含着一个可以用来发送通知的方法:notify

生成数据库

Laravel 支持通过多种频道发送通知,包括邮件、短信 (通过 Nexmo),以及 Slack。通知还能存储到数据库以便后续在 Web 页面中显示。这里我们则使用存储到数据库的方式。

php artisan notifications:table

php artisan migrate

生成通知类

Laravel 中的一条通知就是一个类 (通常存放在 app/Notifications 文件夹下)。

php artisan make:notification InvoicePaid

然后修改 app/Notifications/InvoicePaid:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class InvoicePaid extends Notification
{
    public $invoice;

    /**
     * InvoicePaid constructor.
     * @param $invoice
     */
    public function __construct($invoice)
    {
        $this->invoice = $invoice;
    }

    /**
     * 这里我们使用的 database 通道
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['database'];
    }

    /**
     * 使用 database 通道需要定义 toDatabase 方法
     * @param $notifiable
     * @return array
     */
    public function toDatabase($notifiable)
    {
        // 将会存入 notifications 表的 data 字段中
        return [
            'invoice_id' => $this->invoice->id, // 通知ID
            'type' => $this->invoice->type, // 通知类型
            'title' => $this->invoice->title,// 通知标题
            'content' => $this->invoice->content,// 通知内容
        ];
    }
}

触发通知

这里我们设置在创建通知后触发发送给用户。

创建 Observer 观察者

文档 - 观察者

php artisan make:observer NoticeObserver

该命令会在 app/Observers 文件夹下创建 NoticeObserver.php 文件。

编辑 NoticeObserver.php :

<?php

namespace App\Observers;

use App\Models\Notice;
use App\Models\User;
use App\Notifications\InvoicePaid;

class NoticeObserver
{
    /**
     * 处理 Notice 「created」事件
     */
    public function created(Notice $notice)
    {
        $users = User::all();

        foreach ($users as $user) {
            $user->notify(new InvoicePaid($notice)); // 发送通知
        }

    }
}

然后在 AppServiceProvider.php 中注册观察者的示例:

public function boot()
{
   // ...
   Notice::observe(NoticeObserver::class);
}

这样在创建公告完成后就会发送给所有用户通知。

通知 trait

User 模型带有的 Illuminate\Notifications\Notifiable trait 里,有获取通知,获取未读通知,标记通知已读等方法。

获取通知

$user = User::find(1);

foreach ($user->notifications as $notification) {
    echo $notification->type;
}

获取未读通知

$user = User::find(1);

foreach ($user->unreadNotifications as $notification) {
    echo $notification->type;
}

标记通知已读

$user = User::find(1);

foreach ($user->unreadNotifications as $notification) {
    $notification->markAsRead();
}