Yii2 类级别的事件(Class-Level Event Handlers)

文件结构 Structure

├── ...
├── components
│   └── SampleEventComponent.php
├── config
│   └── web.php
├── controllers
│   └── SiteController.php
├── events
│   ├── BaseEvent.php
│   ├── SampleEvent.php
│   └── TestEvent.php
├── interfaces
│   └── EventInterface.php
└── yii

启动 Bootstrap

create SampleEventComponent and load when app bootstrapped.

// config/web.php
$config = [
    ...
    'bootstrap' => ['log', 'sampleEvent'],
    'components' => [
        'sampleEvent' => [
            'class' => \app\components\SampleEventComponent::class
        ]
        'log' => [
            'traceLevel' => YII_DEBUG ? 3 : 0,
            'targets' => [
                [
                    'class' => 'yii\log\FileTarget',
                    'levels' => ['error', 'warning', 'info'],
                    'logVars' => []
                ],
            ],
        ],
    ],
    ...
];

Create SampleEventComponent

// components/SampleEventComponent.php
namespace app\components;

use Yii;
use yii\base\Component;
use yii\base\Event;
use app\interfaces\EventInterface;
use app\events\SampleEvent;
use app\events\TestEvent;

class SampleEventComponent extends Component
{
  public function init()
  {
    Yii::info(__METHOD__ . ' init.');

    $handler = function (EventInterface $event) {
      Yii::info(get_class($event) . ' is inserted');
      $event->sendMessage();
    };

    Event::on(EventInterface::class, TestEvent::EVENT_NAME, $handler);
    Event::on(EventInterface::class, SampleEvent::EVENT_NAME, $handler);
  }
}

Create EventInterface

// interfaces/EventInterface.php
namespace app\interfaces;

interface EventInterface
{
  public function getMessage(): array;

  public function sendMessage();
}

Create Events

  1. create BaseEvent
// events/BaseEvent.php
namespace app\events;

use app\interfaces\EventInterface;
use Yii;
use yii\base\Event;

abstract class BaseEvent extends Event implements EventInterface
{
  protected array $message;

  const EVENT_NAME = 'event.abstract';

  public function __construct(array $data)
  {
    $this->message = [
      'event_name' => static::EVENT_NAME,
      'data' => $data
    ];
  }

  public function getMessage(): array
  {
    return $this->message;
  }

  public function sendMessage()
  {
    Yii::info($this->getMessage());
    Yii::info(__METHOD__ . ' message was sent.');
  }
}
  1. create SampleEvent
// events/SampleEvent.php
namespace app\events;

class SampleEvent extends BaseEvent
{
  const EVENT_NAME = 'event.sample';
}
  1. create TestEvent
// events/TestEvent.php
namespace app\events;

class TestEvent extends BaseEvent
{
  const EVENT_NAME = 'event.test';
}

Trigger Events

  Event::trigger(
      EventInterface::class,
      TestEvent::EVENT_NAME,
      new TestEvent([1, 2, date('Y-m-d H:i:s')])
  );

  Event::trigger(
      EventInterface::class,
      SampleEvent::EVENT_NAME,
      new SampleEvent([3, 4, date('Y-m-d H:i:s')])
  );

Test

2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] app\components\SampleEventComponent::init init.
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] app\events\TestEvent is inserted
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] [
    'event_name' => 'event.test',
    'data' => [
        1,
        2,
        '2022-01-29 19:36:39',
    ],
]
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] app\events\BaseEvent::sendMessage message was sent.
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] app\events\SampleEvent is inserted
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] [
    'event_name' => 'event.sample',
    'data' => [
        3,
        4,
        '2022-01-29 19:36:39',
    ],
]
2022-01-29 19:36:39 [172.19.0.1][-][-][info][application] app\events\BaseEvent::sendMessage message was sent.