От автора: в этой статье мы рассмотрим основы того, как управляются в 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.