Пользовательские события в 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\ExampleEventSubscriber@sendEmailNotification' ); $events->listen( 'App\Events\ClearCache', 'App\Listeners\ExampleEventSubscriber@warmUpCache' ); }
}

Метод 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.