Я прошел через документацию и все статьи в Yii2 events
, найденные с помощью Google. Может ли кто-нибудь предоставить мне хороший пример того, как события могут использоваться в Yii2 и где это может показаться логичным?
Как использовать события в yii2?
Ответ 1
Я могу объяснить события на простом примере. Допустим, вы хотите сделать несколько вещей, когда пользователь впервые регистрируется на сайте, например:
- Отправить письмо администратору.
- Создать уведомление.
- Вы называете это.
Вы можете попытаться вызвать несколько методов после успешного сохранения объекта пользователя. Может быть так:
if($model->save()){
$mailObj->sendNewUserMail($model);
$notification->setNotification($model);
}
Пока это может показаться нормальным, но что, если количество требований со временем будет расти? Скажите, 10 вещей должно произойти после того, как пользователь зарегистрировался? События пригодятся в подобных ситуациях.
Основы событий
События состоят из следующего цикла.
- Вы определяете событие. Скажем, регистрация нового пользователя.
- Вы называете это в вашей модели. Возможно добавление константы в модели
User
. Например,const EVENT_NEW_USER='new_user';
, Это используется для добавления обработчиков и для запуска события. - Вы определяете метод, который должен что-то делать, когда происходит событие. Например, отправка письма администратору. У него должен быть параметр
$event
. Мы называем этот метод обработчиком. - Вы присоединяете этот обработчик к
model
используя методon()
. Вы можете вызывать этот метод столько раз, сколько пожелаете - просто вы можете прикрепить более одного обработчика к одному событию. - Вы инициируете событие, используя
trigger()
.
Обратите внимание, что все методы, упомянутые выше, являются частью класса Component
. Почти все классы в Yii2 унаследовали от этого класса. Да, ActiveRecord
тоже.
Пусть код
Для решения вышеупомянутой проблемы у нас может быть модель User.php
. Я не буду писать весь код здесь.
// in User.php i've declared constant that stores event name
const EVENT_NEW_USER = 'new-user';
// say, whenever new user registers, below method will send an email.
public function sendMail($event){
echo 'mail sent to admin';
// you code
}
// one more hanlder.
public function notification($event){
echo 'notification created';
}
Здесь нужно помнить, что вы не обязаны создавать методы в классе, который создает событие. Вы можете добавить любой статический, нестатический метод из любого класса.
Мне нужно прикрепить вышеуказанные обработчики к событию. Основной способ, который я сделал, - это использовать метод AR init()
. Итак, вот как:
// this should be inside User.php class.
public function init(){
$this->on(self::EVENT_NEW_USER, [$this, 'sendMail']);
$this->on(self::EVENT_NEW_USER, [$this, 'notification']);
// first parameter is the name of the event and second is the handler.
// For handlers I use methods sendMail and notification
// from $this class.
parent::init(); // DON'T Forget to call the parent method.
}
Последнее, что нужно, это вызвать событие. Теперь вам не нужно явно вызывать все необходимые методы, как мы это делали ранее. Вы можете заменить его следующим:
if($model->save()){
$model->trigger(User::EVENT_NEW_USER);
}
Все обработчики будут вызваны автоматически.
Ответ 2
Для "глобальных" событий.
При желании вы можете создать специализированный класс событий
namespace your\handler\Event\Namespace;
class EventUser extends Event {
const EVENT_NEW_USER = 'new-user';
}
определите хотя бы один класс обработчика:
namespace your\handler\Event\Namespace;
class handlerClass{
// public AND static
public static function handleNewUser(EventUser $event)
{
// $event->user contain the "input" object
echo 'mail sent to admin for'. $event->user->username;
}
}
Внутри составной части config под (в этом случае) пользовательский компонент вставляет вам событие:
'components' => [
'user' => [
...
'on new-user' => ['your\handler\Event\Namespace\handlerClass', 'handleNewUser'],
],
...
]
Затем в вашем коде вы можете вызвать событие:
Yii::$app->user->trigger(EventUser::EVENT_NEW_USER, new EventUser($user));
ADD
Вы также можете использовать закрытие:
- позволяет IDE "обнаруживать" использование функции (для навигации по коду)
- Поместите некоторый (маленький) код, управляющий событием
Пример:
'components' => [
'user' => [
...
'on new-user' => function($param){ your\handler\Event\Namespace\handlerClass::handleNewUser($param);},
'on increment' => function($param){ \Yii::$app->count += $param->value;},
],
...
]
Ответ 3
По умолчанию Yii2 уже предоставляет некоторую декларацию о событиях, вы можете прочитать больше об объяснении на BaseActiveRecord.
Вы можете использовать эту переменную так же, как декларировать ее вручную.
public function init()
{
parent::init();
$this->on(self::EVENT_AFTER_INSERT, [$this, 'exampleMethodHere']);
}