Laravel事件系统与消息通知在实际程序中的应用

文章目录

        • 事件系统介绍
        • 消息通知介绍
        • 应用场景
        • 代码示例
          • 开发前配置
          • 注册程序代码 (app\Http\Controllers)
          • 注册事件监听器映射关系(app/Providers/EventServiceProvider.php)
          • 执行事件生成artisan命令
          • 定义事件(app\Events)
          • 定义事件监听(app\Listeners)
          • 创建发送邮件通知
          • 定义消息通知(app/Notifications)
          • 监控队列
          • 总结

事件系统介绍

Laravel 的事件提供了一个简单的观察者实现,允许你在应用中订阅和监听各种发生的事件。

事件类通常放在 app/Events 目录下,而这些事件类的监听器则放在 app/Listeners 目录下,事件系统在程序解耦方面是非常好的解决方案,事件通常应用于程序已完成之后的操作。

消息通知介绍

Laravel 支持通过多种频道发送通知,包括邮件、短信 (通过 Nexmo),以及 Slack。通知还能存储到数据库以便后续在 Web 页面中显示,目前社区多数通知频道为国外产品如Facebook,Twitter等,一般来说我们都是用来做数据库通知,邮件通知。

应用场景

在用户注册程序中,现在有一个需求,要求注册成功后给用户邮箱发送注册成功邮件,这时可能大多数人都会采用直接在这段注册程序后面接着写发送邮件代码或者封装方法这样的直观写法。

但是后期如果又有一个新的需求,在用户注册成功后不只发送邮件还要拿到用户信息去绑定其他服务,在或者又增加发送短信的服务,这样的话这个注册程序里面已经加了很多东西,导致程序臃肿其他方法不可复用。

这时候,就可以用到事件功能了。

代码示例

以下代码利用Laravel自带的事件系统,消息通知,队列实现了用户注册成功后各类其他异步操作。虽说这三种自带功能,在Laravel中属于进阶系列,但是如果仔细查阅文档捋顺逻辑关系其实并不是太复杂。

该示例部分说明在代码注释内,文档内不做过多文字说明。

开发前配置
//队列使用redis
QUEUE_CONNECTION=redis
//配置好邮件发送内容
MAIL_DRIVER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=1025
注册程序代码 (app\Http\Controllers)

    
namespace App\Http\Controllers;

use App\Events\UserRegister;
use App\Models\User;

class RegisterController extends Controller
{
    public function postRegiste()
    {
        //模拟注册
        $user = User::create([
           'name' => 'xxx',
            ......
        ]);
		
        //此处为触发事件操作,该事件主要完成了发送邮件
        $this->afterRegister($user);
        
        return xxx;
    }
    
    /**
     * 事件
     *
     * @param User $user
     */
    protected function afterRegister(User $user)
    {
        event(new UserRegister($user));
    }

}
注册事件监听器映射关系(app/Providers/EventServiceProvider.php)
//在该变量下注册映射关系
protected $listen = [
    .....
    // 注册成功事件监听,可以是多个,实现跟注册程序解耦
    'App\Events\UserRegister' => [
        // 发送邮件
        'App\Listeners\SendUserRegisterMail',
        //发送短信
        ......
        //绑定服务
        ......
    ],
];
执行事件生成artisan命令
php artisan event:generate
//该命令完成后,会分别自动在 app/Events和app/Listensers目录下生成 UserRegister.php和SendUserRegisterMail.php文件。
定义事件(app\Events)

namespace App\Events;

use App\Models\User;

use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class UserRegister
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    protected $user;

    /**
     * Create a new event instance.
     *
     * @param User $order
     * @return void
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * 获取用户
     * @return User
     */
    public function getUser()
    {
        return $this->user;
    }
}
定义事件监听(app\Listeners)


namespace App\Listeners;

use App\Events\UserRegister;
use App\Notifications\UserRegisterNotification;
use Illuminate\Contracts\Queue\ShouldQueue;

/**
 * implements ShouldQueue 代表异步监听器
 *
 * Class SendOrderPaidMail
 * @package App\Listeners
 */
class SendUserRegisterMail implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param UserRegister $event
     * @return void
     */
    public function handle(UserRegister $event)
    {
        //从事件对象中取出对应的用户
        $user = $event->getUser();

        //调用 notify 方法来发送通知,此处用到了laravel自带的消息通知功能
        $user->notify(new UserRegisterNotification($user));
    }
}
创建发送邮件通知
php artisan make:notification UserRegisterNotification
    
//这条命令会在 app/Notifications 目录下生成一个新的通知类
定义消息通知(app/Notifications)


namespace App\Notifications;

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

class UserRegisterNotification extends Notification implements ShouldQueue
{
    use Queueable;

    protected $user;

    /**
     * Create a new notification instance.
     *
     * @param Order $order
     */
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    /**
     * 我们只需要通过邮件通知,因此这里只需要一个 mail 即可
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * 使用 toMail 方法进行邮件发送,此处是将邮件推送至队列
     *
     * @param mixed $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject('注册成功') // 邮件标题
            ->greeting($this->user->name . '您好:')  // 欢迎词
            ->line('您于'.$this->user->created_at->format('m-d H:i').'注册成功。') // 邮件内容
            ->action('查看个人信息', route('user.show', [$this->user->id]))   // 邮件中的按钮及对应链接,此处为举例
            ->line('感谢您使用'.config('app.name').'!') //文本内容
            ->line('xxxxxxxxxxxxxxxxx')
            ->level('primary'); //按钮样式,默认为 success
    }
}

邮件通知可自定义发送模板,文档地址:https://xueyuanjun.com/post/21528

监控队列
php artisan queue:listen

//队列监控建议使用 Supervisor 工具做进程守护    
总结

以上就是通过Laravel自带服务实现了用户注册成功后的各种操作,不但可以提高程序的执行效率,也彻底解决了程序之间的高耦合。

日常中还有很多这样的场景,比如说用户支付完成后需要同时修改商品数,也需要给用户发送邮件,短信通知等,都可以利用事件系统完成。

你可能感兴趣的:(Laravel)