laravel8中事件系统

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

一、事件监听器与事件订阅者的区别

其实就一句话:
Each event can have multiple listeners, but a listener can't listen to more than a single event. If you want a class listening to many events, you should use the Event Subscribers.
每个事件均可有多个监听器,但是一个监听器只能监听一个事件。如果想在一个类中监听多个事件,就需要使用事件订阅者

二、事件监听器

1、事件类通常放在 app/Events 目录下,而这些事件类的监听器则放在 app/Listeners 目录下

2、生成事件和监听器  

(1)app/Providers/EventServiceProvider.php,执行命令 php artisan event:generate即可

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;


class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array<class-string, array<int, class-string>>
*/
protected $listen = [
'App\Events\OrderShipped' => [
'App\Listeners\SendShipmentNotification',
],
];

}

(2)app/Events/OrderShipped.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;
use App\Models\Order;

class OrderShipped
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
    public $order;
    /**
     * 创建一个事件实例
     *
     * @param  \App\Models\Order  $order
     * @return void
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

}

(3)app/Listeners/SendShipmentNotification.php

<?php

namespace App\Listeners;

use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Log;

class SendShipmentNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  \App\Events\OrderShipped  $event
     * @return void
     */
    public function handle(OrderShipped $event)
    {
    print_r('订单name:');
    var_dump($event->order->name);
    Log::info('这里可以添加一些需要的操作');
   } 
}

(4)app/Http/Controllers/OrderController.php

<?php

namespace App\Http\Controllers;

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

class OrderController extends Controller
{
    /**
     * 为给定的订单发货
     *
     * @param  int  $orderId
     * @return Response
     */
    public function ship($orderId)
    {
        $order = Order::findOrFail($orderId);

        // 订单发货逻辑(两种方式都可以分发事件)
        //event(new OrderShipped($order));
        OrderShipped::dispatch($order);
    }
}

(5)添加路由

Route::get(
    '/order/{id}',
    [OrderController::class, 'ship']
);

(6)运行结果

三、事件订阅

(1)编写事件订阅者app/Listeners/TreasureLogs.php,订阅了两个事件App/Events/SignApp/Events/Conver(这里可以使用命令生成这两个事件

<?php

namespace App\Listeners;
use Illuminate\Support\Facades\Log;

class TreasureLogs
{

    public function subscribe($events)
    {
        $events->listen(
            'App\Events\Sign',
            [TreasureLogs::class, 'signLogs']
        );

        $events->listen(
            'App\Events\Conver',
            [TreasureLogs::class, 'converLogs']
        );
    }

    public function signLogs($events)
    {
        echo 'signLogs';
        Log::info('sign');
    }

    public function converLogs($events)
    {
        echo 'converLogs';
        Log::info('conver');
    }

}

(2)注册事件订阅者 app/Providers/EventServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;


class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array<class-string, array<int, class-string>>
     */
    protected $listen = [
        'App\Events\OrderShipped' => [
            'App\Listeners\SendShipmentNotification',
        ],
    ];

    /**
     * 被注册的订阅者类
     *
     * @var array
     */
    protected $subscribe = [
        'App\Listeners\TreasureLogs',
    ];

}

(3)app/Http/Controllers/PhotoController.php

<?php

namespace App\Http\Controllers;

use App\Models\Photo;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Events\Sign;
use App\Events\Conver;

class PhotoController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        echo '事件分发:';
        echo('----Sign----');
        Sign::dispatch();
        echo('----Conver----');
        Conver::dispatch();
    }

}

(4)路由配置

Route::get(
    '/photo',
    [PhotoController::class, 'index']
)->name('profile');

(5)运行结果

posted @ 2022-03-01 15:56  艾薇-Ivy  阅读(208)  评论(0编辑  收藏  举报