Есть три метода, при срабатывании которых я хочу записывать данные в лог-таблицу.
Я могу генерировать событие в этих трех методах.
Вопрос в том, где нужно поставить обработчик события, чтобы она автоматически срабатывал, как только наступит это событие?
Если это делать в контроллере, то кажется это глупо, зачем тогда вообще события.
Yii2 события
Re: Yii2 события
Если есть событие:
То можно навешиваться глобально:
и в контроллере вызывать:
Или как шину событий использовать Yii::$app:
и потом вызывать в любом месте:
Если же пишете unit-тесты, то глобальные обработчики будут постоянно вызываться и в тестах. Поэтому сделайте отдельный EventDispatcher, который в тестах можно будет мОкнуть при необходимости:
и зарегистрируйте в DIC:
чтобы прокидывать его во все места через DIC:
Или зарегистрируйте как компонент:
чтобы он стал доступен через Yii::$app:
Код: Выделить всё
class OrderCreated extends Event
{
public $order;
public function __construct(Order $order)
{
$this->order = $order;
}
}
Код: Выделить всё
class SetUp implements BootstrapInterface
{
public function bootstrap($app)
{
Event::on(OrderController::class, OrderController::EVENT_ORDER_CREATED, function (OrderCreated $event) {
Yii::info('Order #' . $event->order->id . ' is created', 'app');
});
Event::on(OrderController::class, OrderController::EVENT_ORDER_PAYD, [OrderPaydListener::class, 'onOrderPayd']);
}
}
Код: Выделить всё
$this->trigger(self::EVENT_ORDER_CREATED, new OrderCreated($order);
Код: Выделить всё
class SetUp implements BootstrapInterface
{
public function bootstrap($app)
{
$app->on(OrderCreated::class, function (OrderCreated $event) {
Yii::info('Order #' . $event->order->id . ' is created', 'app');
});
$app->on(OrderPayd::class, [OrderPaydListener::class, 'onOrderPayd']);
}
}
Код: Выделить всё
Yii::$app->trigger(OrderCreated::class, new OrderCreated($order));
Код: Выделить всё
class EventDispatcher extends Component
{
public function dispatch($event)
{
$this->trigger(get_class($event), $event);
}
}
Код: Выделить всё
class SetUp implements BootstrapInterface
{
public function bootstrap($app)
{
$container = Yii::$container;
$container->setSingleton(EventDispatcher::class, function () {
$dispatcher = new EventDispatcher();
$dispatcher->on(OrderCreated::class, function (OrderCreated $event) {
Yii::info('Order #' . $event->order->id . ' is created', 'app');
};
$dispatcher->on(OrderPayd::class, [OrderPaydListener::class, 'onOrderPayd']);
return $dispatcher;
});
}
}
Код: Выделить всё
class OrderService
{
private $dispatcher;
public function __construct(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
public function create(OrderForm $form)
{
$order = Order::create(...);
...
$this->dispatcher->dispatch(new OrderCreated($order));
}
}
Код: Выделить всё
class SetUp implements BootstrapInterface
{
public function bootstrap($app)
{
$app->set('eventDispatcher', function () {
$dispatcher = new EventDispatcher();
$dispatcher->on(OrderCreated::class, function (OrderCreated $event) {
Yii::info('Order #' . $event->order->id . ' is created', 'app');
};
$dispatcher->on(OrderPayd::class, [OrderPaydListener::class, 'onOrderPayd']);
return $dispatcher;
});
}
}
Код: Выделить всё
Yii::$app->eventDispatcher->dispatch(new OrderCreated($order));
Re: Yii2 события
С диспетчером самый красивый код )