Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)
В этой статье мы рассмотрим основы управления событиями в 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
.
Вспомогательная функция event используется для создания события из любого места приложения. Когда событие генерируется, 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- события и слушатели. Они основаны на шаблоне проектирования наблюдатель, который позволяет вам увеличивать события на уровне приложений и разрешать другим модулям прослушивать эти события и реагировать соответствующим образом.
Вам интересен Laravel или хотите расширить свои знания, сайт или приложение с помощью расширений? У нас есть множество вещей, которые вы можете изучать на Envato Market.
Оставляйте свои комментарии ниже!