21
Мар
2018

Пользовательские события в Laravel

Пользовательские события в Laravel

От автора: в этой статье мы рассмотрим основы того, как управляются в Laravel события. Это одна из важных функций, которые вы, как разработчик, должны иметь в своем арсенале. По мере продвижения мы также воспользуемся этой возможностью, чтобы создать реальный пример пользовательского события и обработчика, и это конечная цель этой статьи.

Концепция событий в Laravel основана на очень популярном шаблоне проектирования программного обеспечения — шаблоне наблюдателя. В этом шаблоне система должна поднимать события, когда что-то происходит, чтобы вы могли определить обработчики, которые следят за этими событиями и, соответственно, реагируют. Это действительно полезная функция, позволяющая отделить компоненты в системе, которая в противном случае привела бы к тесно связанному коду.

Например, скажите, что вы хотите уведомить все модули в системе, когда кто-то заходит на ваш сайт. Таким образом, он позволяет среагировать на это событие, будь то отправка электронной почты или уведомление в приложении или, что-то подобное, что среагирует на событие входа в систему.

Основы событий и обработчиков

В этом разделе мы рассмотрим способ Laravel для реализации событий и обработчиков в основном фреймворке. Если вы знакомы с архитектурой Laravel, вы, вероятно, знаете, что Laravel реализует концепцию поставщика услуг, которая позволяет вводить различные сервисы в приложение.

Аналогичным образом, Laravel предоставляет встроенный класс EventServiceProvider.php который позволяет определять отображения обработчика событий для приложения.

Вложим app/Providers/EventServiceProvider.php файл

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\SomeEvent' => [
        'App\Listeners\EventListener',
        ],
    ];
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
        //
    }
}

Давайте внимательно рассмотрим свойство $listen , которое позволяет определить массив событий и связанных с ним обработчиков. Ключи массива соответствуют событиям в системе, и их значения соответствуют обработчикам, которые будут срабатывать, когда соответствующее событие будет поднято в системе.

Я предпочитаю рассматривать темы на реальном примере, чтобы продемонстрировать их. Как вы, вероятно, знаете, Laravel предоставляет встроенную систему аутентификации, которая облегчает такие функции, как вход в систему, регистрация и т.п.

Допустим, что вы хотите получить уведомление по электронной почте в качестве меры безопасности, когда кто-то войдет в приложение. Если Laravel не поддерживает функцию обработчика событий, возможно, вы закончили редактирование основного класса или каким-либо другим способом подключили код, который отправляет электронное письмо.

На самом деле, удача на вашей стороне, так как Laravel помогает вам решить эту проблему с помощью обработчика событий. Давайте проверим app/Providers/EventServiceProvider.php файл, чтобы он выглядел следующим образом.

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'Illuminate\Auth\Events\Login' => [
        'App\Listeners\SendEmailNotification',
        ],
    ];
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
        //
    }
}

Illuminate\Auth\Events\Login — это событие, которое будет поднято плагином Auth когда кто-то войдет в приложение. Мы связали это событие с обработчиком App\Listeners\SendEmailNotification, поэтому при регистрации он будет запущен.

Конечно, вам необходимо определить класс обработчика App\Listeners\SendEmailNotification . Как всегда, Laravel позволяет вам создать код шаблона обработчика, используя команду artisan.

php artisan event:generate

Эта команда генерирует классы событий и обработчиков, перечисленные в $listen.

В нашем случае событие Illuminate\Auth\Events\Login уже существует, поэтому она создает класс обработчика App\Listeners\SendEmailNotification. Фактически, она в первую очередь создала бы класс событий Illuminate\Auth\Events\Login, если бы его не существовало.

Давайте посмотрим на класс обработчика, созданный в app/Listeners/SendEmailNotification.php.

<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendEmailNotification
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    /**
     * Handle the event.
     *
     * @param  Login  $event
     * @return void
     */
    public function handle(Login $event)
    {
         
    }
}

Это метод handle который будет вызываться с соответствующими зависимостями всякий раз, когда слушаиель запускается. В нашем случае аргумент $event должен содержать контекстуальную информацию о регистрации в журнале событий пользовательской информации.

И мы можем использовать объект $event для дальнейшей обработки в методе handle . В нашем случае мы хотим отправить уведомление по электронной почте зарегистрированному пользователю.

Пересмотренный метод handle может выглядеть примерно так:

public function handle(Login $event)
{
    // get logged in user's email and username
    $email = $event->user->email;
    $username = $event->user->name;
     
    // send email notification about login
}

Вот как вы должны использовать функцию событий в Laravel. В следующем разделе мы продолжим работу и создадим настраиваемое событие и связанный с ним класс обработчика.

Создание пользовательского события

Примерный сценарий, который мы будем использовать для нашего примера, выглядит так:

Приложению необходимо чистить кэш в системе в определенные моменты. Во время чистки кэша мы поднимем событие CacheClear вместе с контекстной информациейи передадим групповые ключи кэша вместе с событием, которое было очищено.

Другие модули в системе могут ждать событие CacheClear и выполнять код, который нагревает связанные кэши

Давайте рассмотрим файл app/Providers/EventServiceProvider.php и зарегистрируем наши пользовательские события и обработчиков.

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\ClearCache' => [
        'App\Listeners\WarmUpCache',
        ],
    ];
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
        //
    }
}

Как вы можете видеть, мы определили событие App\Events\ClearCache и связанный с ним класс обработчика App\Listeners\WarmUpCache под свойством $listen.

Затем нам нужно создать связанные файлы классов. Напомним, что вы всегда можете использовать команду artisan для генерации базового шаблона.

php artisan event:generate

Это должно было создать класс события в app/Events/ClearCache.php и класс обработчика в app/Listeners/WarmUpCache.php.

С некоторыми изменениями класс app/Events/ClearCache.php должен выглядеть следующим образом:

<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ClearCache
{
    use Dispatchable, InteractsWithSockets, SerializesModels;
     
    public $cache_keys = [];
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Array $cache_keys)
    {
        $this->cache_keys = $cache_keys;
    }
    /**
     * Get the channels the event should broadcast on.
     *
     * @return Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('channel-name');
    }
}

Как вы, наверное, заметили, мы добавили новое свойство $cache_keys, которое будет использоваться для хранения информации, переданной вместе с событием. В нашем случае мы будем передавать групповой кэш, который был сброшен.

Давайте посмотрим на класс обработчика с обновленным методом handle в app/Listeners/WarmUpCache.php.

<?php
namespace App\Listeners;
use App\Events\ClearCache;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class WarmUpCache
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    /**
     * Handle the event.
     *
     * @param  ClearCache  $event
     * @return void
     */
    public function handle(ClearCache $event)
    {
        if (isset($event->cache_keys) && count($event->cache_keys)) {
            foreach ($event->cache_keys as $cache_key) {
                // generate cache for this key
                // warm_up_cache($cache_key)
            }
        }
    }
}

Когда вызывается обработчик, метод handle передается с экземпляром связанного события. В нашем случае это должен быть экземпляр события ClearCache который будет передан в качестве первого аргумента методу handle.

Далее просто вопрос итерации каждого ключа кэша и разгонки связанных кэшей.

Теперь у нас есть все, что нужно для проверки. Давайте быстро создадим файл контроллера в app/Http/Controllers/EventController.php, чтобы продемонстрировать, как можно поднять событие.

<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Library\Services\Contracts\CustomServiceInterface;
use App\Post;
use Illuminate\Support\Facades\Gate;
use App\Events\ClearCache;
class EventController extends Controller
{
    public function index()
    {
        // ...
         
        // you clear specific caches at this stage
        $arr_caches = ['categories', 'products'];
         
        // want to raise ClearCache event
        event(new ClearCache($arr_caches));
         
        // ...
    }
}

При создании экземпляра события ClearCache мы передали массив ключей кэша в качестве первого аргумента.

Вспомогательная функция события используется для создания события из любого места приложения. Когда событие поднимается, Laravel вызывает все обработчики наблюдением за конкретным событием.

В нашем случае App\Listeners\WarmUpCache настроен на наблюдение за App\Events\ClearCache . Таким образом, handle метод App\Listeners\WarmUpCache вызывает обработчик, когда событие возникает из контроллера. Остальное разогревает кэш, который был очищен!

Так можно создавать пользовательские события в своем приложении и работать с ними.

Что такое подписчик событий?

Подписчик события позволяет вам подписать несколько обработчиков событий в одном месте. Независимо от того, хотите ли вы логически группировать их или хотите содержать растущие события в одном месте, это подписчик событий, который вы ищете.

Если бы мы реализовали примеры, рассмотренные ранее в этой статье с использованием подписчика событий, то выглядело бы это так:

<?php
// app/Listeners/ExampleEventSubscriber.php
namespace App\Listeners;
class ExampleEventSubscriber
{
    /**
     * Handle user login events.
     */
    public function sendEmailNotification($event) {
        // get logged in username
        $email = $event->user->email;
        $username = $event->user->name;
         
        // send email notification about login...
    }
    /**
     * Handle user logout events.
     */
    public function warmUpCache($event) {
        if (isset($event->cache_keys) && count($event->cache_keys)) {
            foreach ($event->cache_keys as $cache_key) {
                // generate cache for this key
                // warm_up_cache($cache_key)
            }
        }
    }
    /**
     * Register the listeners for the subscriber.
     *
     * @param  Illuminate\Events\Dispatcher  $events
     */
    public function subscribe($events)
    {
        $events->listen(
            'Illuminate\Auth\Events\Login',
            'App\Listeners\[email protected]'
        );
         
        $events->listen(
            'App\Events\ClearCache',
            'App\Listeners\[email protected]'
        );
    }
}

Метод subscribe отвечает за регистрацию обработчиков. Первый аргумент метода subscribe — это экземпляр класса Illuminate\Events\Dispatcher, который можно использовать для привязки событий к обработчикам с использованием метода listen.

Первый аргумент метода listen — это событие, которое вы хотите проследить, а второй аргумент — это обработчик, который будет вызываться при создании события.

Таким образом, вы можете определить несколько событий и обработчиков в самом классе подписчика. Класс подписчика события не будет загружен автоматически. Вам необходимо зарегистрировать его в классе EventServiceProvider.php под свойством $subscriber, как показано в следующем фрагменте.

<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
    /**
     * The subscriber classes to register.
     *
     * @var array
     */
    protected $subscribe = [
        'App\Listeners\ExampleEventSubscriber',
    ];
    /**
     * Register any events for your application.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
        //
    }
}

Итак, это был класс подписчиков событий, и с ним мы достигли конца этой статьи.

Заключение

Сегодня мы обсудили пару интересных особенностей Laravel-событий и обработчиков. Они основаны на шаблоне проектирования обработки, который позволяет вам увеличивать события на уровне приложений и разрешать другим модулям следить за этими событиями и реагировать соответствующим образом.

Автор: Sajal Soni

Источник: https://code.tutsplus.com/

Редакция: Команда webformyself.

Источник: https://webformyself.com/polzovatelskie-sobytiya-v-laravel/

Тебе может это понравится...

Добавить комментарий