События ( Events )
- Использование
- Подписка на события
- Где писать код ?
- Подписка на событие с приоритетом
- Прерывание обработки события
- Обработчики по шаблону (wildcard)
- Вызов событий ( Firing events )
- Передача аргументов по ссылке
- Очередь событий
- Использование классов в качестве слушателей
- Определение метода-подписчика
- Определение класса-подписчика
- Трейт
# Использование
Класс Event
содержит простую реализацию концепции Observer ("Наблюдатель"), что позволяет Вам подписываться на уведомления о событиях (listen for events) в вашем приложении. Пример:
Event::listen('auth.login', function($user) {
$user->last_login = new DateTime;
$user->save();
});
Вы можете получить доступ к этому событию при помощи метода Event::fire
, который позволяет расширить логику Вашего приложения:
Event::fire('auth.login', [$user]);
# Подписка на события
Вы можете использовать метод Event::listen
в любом месте. Первый аргумент - название события.
Event::listen('acme.blog.myevent', ...);
Второй аргумент - функция-замыкание с произвольными аргументами.
Event::listen('acme.blog.myevent', function($arg1, $arg2) {
// Do something
});
Вы также можете передать ссылку на вызываемый объект или на класс.
Event::listen('auth.login', [$this, 'LoginHandler']);
Примечание: Вы можете указать все аргументы, их часть или ничего. В любом случае событие не будет вызывать никаких ошибок, если их не указано слишком много.
# Где писать код ?
Наиболее подходящее место - метод boot
в файле регистрации плагина.
class Plugin extends PluginBase
{
[...]
public function boot()
{
Event::listen(...);
}
}
Вы также можете использовать файл init.php в папке с плагином. Пример:
<?php
Event::listen(...);
# Подписка на событие с приоритетом
При подписке на событие Вы можете указать приоритет. Обработчики с более высоким приоритетом будут вызваны перед теми, чей приоритет ниже, а обработчики с одинаковым приоритетом будут вызываться в порядке их регистрации.
// Run first
Event::listen('auth.login', function() { ... }, 10);
// Run second
Event::listen('auth.login', function() { ... }, 5);
# Прерывание обработки события
Иногда Вам может быть нужно пропустить вызовы других обработчиков события. Вы можете сделать это, вернув значение false
:
Event::listen('auth.login', function($event) {
// Handle the event
return false;
});
# Обработчики по шаблону (wildcard)
Вы можете использовать звёздочки (*) при регистрации обработчика для привязки его ко всем подходящим событиям. Пример:
Event::listen('foo.*', function($param) {
// Handle the event...
});
Используйте метод Event::firing
, для определения того, какое именно событие из подходящих под foo.*
поймано:
Event::listen('foo.*', function($param) {
if (Event::firing() == 'foo.bar') {
// ...
}
});
# Вызов событий ( Firing events )
Вы можете использовать метод Event::fire
в любом месте вашего кода, чтобы сделать логику расширяемой. Это означает, что другие разработчики или даже Ваш собственный код могут «подключиться» к этой точке и добавить новую логику. Первый аргумент - название события.
Event::fire('myevent')
Вы можете использовать в качестве префикса пространство имен, чтобы избежать конфликты с другими плагинами.
Event::fire('acme.blog.myevent');
Второй аргумент - произвольный массив данных, которые будут использоваться в качестве аргументов в методе Event::listen
.
Event::fire('acme.blog.myevent', [$arg1, $arg2]);
Третий аргумент указывает на то, что событие должно прерываться, если возвращаемое значение - "non null". По умолчанию этот аргумент имеет значение false
.
Event::fire('acme.blog.myevent', [...], true);
// Single result, event halted
$result = Event::fire('acme.blog.myevent', [...], true);
// Collection of results, all events fired
$results = Event::fire('acme.blog.myevent', [...]);
# Передача аргументов по ссылке
Вы можете передать переменную по ссылке, чтобы изменить ее содержимое:
// $content = '111'
Event::fire('cms.processContent', [&$content]);
Пример:
Event::listen('cms.processContent', function (&$content) {
$content = $content . 'A';
});
Event::listen('cms.processContent', function (&$content) {
$content = $content . 'B';
});
В итоге: $content = '111AB'
.
# Очередь событий
Вы можете использовать метод Event::queue
, чтобы отложить выполнение события и добавить его в очередь.
Event::queue('foo', [$user]);
Используйте метод Event::flush
, чтобы удалить все события из очереди.
Event::flush('foo');
# Использование классов в качестве слушателей
Вы можете использовать классы для обработки событий.
# Определение метода-подписчика
Вы можете определить класс для обработки событий, передав его название в качестве второго аргумента.
Event::listen('auth.login', 'LoginHandler');
По умолчанию буде вызываться метод handle
класса LoginHandler
:
class LoginHandler
{
public function handle($data)
{
// ...
}
}
Вы можете заменить этот метода на любой другой:
Event::listen('auth.login', 'LoginHandler@onLogin');
# Определение класса-подписчика
Подписчики на события (Event Class Subscribers) - классы, которые могут быть подписаны на несколько событий и содержать сразу несколько обработчиков событий. Такой класс должен иметь метод subscribe
, который принимает в аргументах инстанс диспетчера событий:
class UserEventHandler
{
/**
* Handle user login events.
*/
public function userLogin($event)
{
// ...
}
/**
* Handle user logout events.
*/
public function userLogout($event)
{
// ...
}
/**
* Register the listeners for the subscriber.
*
* @param Illuminate\Events\Dispatcher $events
* @return array
*/
public function subscribe($events)
{
$events->listen('auth.login', 'UserEventHandler@userLogin');
$events->listen('auth.logout', 'UserEventHandler@userLogout');
}
}
После того как класс определён, его можно зарегистрировать следующим образом:
Event::subscribe(new UserEventHandler);
Вы также можете использовать сервис-контейнер для того, чтобы получить объект своего подписчика на события:
Event::subscribe('UserEventHandler');
# Трейт
Вы можете использовать трейт October\Rain\Support\Traits\Emitter
, чтобы связать события с экземпляром объекта внутри вашего класса.
class UserManager
{
use \October\Rain\Support\Traits\Emitter;
}
Этот трейт позволяет "слушать" события при помощи метода bindEvent
.
$manager = new UserManager;
$manager->bindEvent('user.beforeRegister', function($user) {
// Check if the $user is a spammer
});
Метод fireEvent
используется для «выстреливания» события.
$manager = new UserManager;
$manager->fireEvent('user.beforeRegister', [$user]);
Эти события будут происходить только для локального объекта.