Подтвердить что ты не робот

Как использовать события в yii2?

Я прошел через документацию и все статьи в Yii2 events, найденные с помощью Google. Может ли кто-нибудь предоставить мне хороший пример того, как события могут использоваться в Yii2 и где это может показаться логичным?

4b9b3361

Ответ 1

Я могу объяснить события на простом примере. Допустим, вы хотите сделать несколько вещей, когда пользователь впервые регистрируется на сайте, например:

  1. Отправить письмо администратору.
  2. Создать уведомление.
  3. Вы называете это.

Вы можете попытаться вызвать несколько методов после успешного сохранения объекта пользователя. Может быть так:

if($model->save()){
   $mailObj->sendNewUserMail($model);
   $notification->setNotification($model);
}

Пока это может показаться нормальным, но что, если количество требований со временем будет расти? Скажите, 10 вещей должно произойти после того, как пользователь зарегистрировался? События пригодятся в подобных ситуациях.

Основы событий

События состоят из следующего цикла.

  1. Вы определяете событие. Скажем, регистрация нового пользователя.
  2. Вы называете это в вашей модели. Возможно добавление константы в модели User. Например, const EVENT_NEW_USER='new_user'; , Это используется для добавления обработчиков и для запуска события.
  3. Вы определяете метод, который должен что-то делать, когда происходит событие. Например, отправка письма администратору. У него должен быть параметр $event. Мы называем этот метод обработчиком.
  4. Вы присоединяете этот обработчик к model используя метод on(). Вы можете вызывать этот метод столько раз, сколько пожелаете - просто вы можете прикрепить более одного обработчика к одному событию.
  5. Вы инициируете событие, используя 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']);
}