В этой статье мы собираемся изучить основы управления событиями в Laravel. Это одна из важных функций, которую вы, как разработчик, должны иметь в своем арсенале в желаемой среде. По мере продвижения мы также воспользуемся этой возможностью, чтобы создать реальный пример пользовательского события и слушателя, и это также является конечной целью этой статьи.
Концепция событий в Laravel основана на очень популярном паттерне разработки программного обеспечения — паттерне наблюдателя. В этом паттерне система должна вызывать события, когда что-то происходит, и вы можете определить слушателей, которые слушают эти события и реагируют соответствующим образом. Это действительно полезная функция, позволяющая отделить компоненты системы, которые в противном случае привели бы к созданию тесно связанного кода.
Например, скажем, вы хотите уведомить все модули в системе, когда кто-то заходит на ваш сайт. Таким образом, он позволяет им реагировать на это событие входа в систему, независимо от того, идет ли речь об отправке электронного письма или уведомления в приложении, или, в этом отношении, обо всем, что хочет отреагировать на это событие входа в систему.
Основы событий и слушателей
В этом разделе мы рассмотрим способ реализации событий и слушателей в базовой среде Laravel. Если вы знакомы с архитектурой Laravel, вы, вероятно, знаете, что Laravel реализует концепцию поставщика услуг, который позволяет внедрять различные приложения в приложение.
Аналогичным образом, Laravel предоставляет встроенный класс EventServiceProvider.php который позволяет нам определять отображения прослушивателей событий для приложения.
Идите вперед и извлеките файл app/Providers/EventServiceProvider.php .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?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 файл app/Providers/EventServiceProvider.php чтобы он выглядел следующим образом.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?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.
|
1
|
php artisan event:generate
|
Эта команда генерирует классы событий и слушателей, перечисленные в свойстве $listen .
В нашем случае событие Illuminate\Auth\Events\Login уже существует, поэтому оно создает только класс прослушивателя App\Listeners\SendEmailNotification . Фактически, он также создал бы класс событий Illuminate\Auth\Events\Login если бы он не существовал в первую очередь.
Давайте посмотрим на класс слушателя, созданный в app/Listeners/SendEmailNotification.php .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?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 может выглядеть примерно так:
|
1
2
3
4
5
6
7
8
|
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 файлу app/Providers/EventServiceProvider.php и зарегистрируем наши пользовательские сопоставления событий и слушателей.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<?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 .
Далее нам нужно создать связанные файлы классов. Напомним, что вы всегда можете использовать команду ремесленника для генерации кода базового шаблона.
|
1
|
php artisan event:generate
|
Это должно было создать класс событий в app/Events/ClearCache.php и класс слушателя в app/Listeners/WarmUpCache.php .
С некоторыми изменениями класс app/Events/ClearCache.php должен выглядеть следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<?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 .
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<?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 чтобы продемонстрировать, как вы можете вызвать событие.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?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 . Таким образом, метод App\Listeners\WarmUpCache прослушивателя App\Listeners\WarmUpCache вызывается, когда событие вызывается из контроллера. Остальное — разогреть кеши, которые были очищены!
Таким образом, вы можете создавать собственные события в вашем приложении и работать с ними.
Что такое подписчик на событие?
Подписчик на событие позволяет вам подписать несколько слушателей событий в одном месте. Независимо от того, хотите ли вы логически сгруппировать прослушиватели событий или хранить растущие события в одном месте, вы ищете именно подписчика событий.
Если бы мы реализовали примеры, обсуждаемые до сих пор в этой статье, с использованием подписчика на событие, это может выглядеть следующим образом.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<?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 в EventServiceProvider.php $subscriber , как показано в следующем фрагменте.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?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 .
Не стесняйтесь выражать свои мысли, используя канал ниже!