Ответ 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);
}
Все обработчики будут вызваны автоматически.