Использование событий

Класс Application компонента Console позволяет вам по желанию подключаться к жизненному циклу консольного приложения через события. Вместо того, чтобы изобретать велосипед, он использует компонент Symfony EventDispatcher, чтобы сделать работу:

1
2
3
4
5
6
7
8
use Symfony\Component\Console\Application;
use Symfony\Component\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();

$application = new Application();
$application->setDispatcher($dispatcher);
$application->run();

Caution

События консоли вызываются только путём выполнения основной команды. Команды, вызванные основной командой, не запустят ни одно событие.

Событие ConsoleEvents::COMMAND

Типичное назначение: Сделать что-либо до запуска любой команды (вроде логирования, какая команда будет выполнена), или отобразить что-то о том событии, которое будет выполнено.

Событие ConsoleEvents::COMMAND запускается прямо перед вызовом любой команды. Слушатели получают событие ConsoleCommandEvent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\ConsoleEvents;

$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
    // получает экземпляр ввода
    $input = $event->getInput();

    // получает экземпляр вывода
    $output = $event->getOutput();

    // получает команду, которая будет выполнена
    $command = $event->getCommand();

    // пишет что-то о команде
    $output->writeln(sprintf('Before running command <info>%s</info>', $command->getName()));

    // получает приложение
    $application = $command->getApplication();
});

Отключение команд внутри слушателей

Используя метод disableCommand(), вы можете отключать команды внутри слушателя. Тогда приложение не будет выполнять команду, а вместо этого вернёт код 113 (определённый в ConsoleCommandEvent::RETURN_CODE_DISABLED). Этот код является одним из зарезервированных кодов завершения для команд консоль, которые подчиняются стандарту C/C++.:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\ConsoleEvents;

$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
    // получает команду, которая будет выполнена
    $command = $event->getCommand();

    // ... проверить, можно ли выполнить команду

    // отключает команду, что приведёт к пропуску команды
    // и возвращению кода 113 из приложения
    $event->disableCommand();

    // возможно включить команду в более позднем слушателе
    if (!$event->commandShouldRun()) {
        $event->enableCommand();
    }
});

Событие ConsoleEvents::ERROR

Типичное назначение: Обрабатывать исключения, вызванные во время выполнения команды.

Каждый раз, когда команда вызывает исключение, включая те, что запускаются из слушателей событий, выполняется событие``ConsoleEvents::ERROR``. Слушатель может обернуть или изменить исключение или сделать что-либо полезное перед тем, как приложение вызовет исключение.

Слушатели получают событие ConsoleErrorEvent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
use Symfony\Component\Console\Event\ConsoleErrorEvent;
use Symfony\Component\Console\ConsoleEvents;

$dispatcher->addListener(ConsoleEvents::ERROR, function (ConsoleErrorEvent $event) {
    $output = $event->getOutput();

    $command = $event->getCommand();

    $output->writeln(sprintf('Oops, exception thrown while running command <info>%s</info>', $command->getName()));

    // получает текущий код завершения (код исключения или код завершения, установленный событием ConsoleEvents::TERMINATE)
    $exitCode = $event->getExitCode();

    // меняет исключение на другое
    $event->setException(new \LogicException('Caught exception', $exitCode, $event->getError()));
});

Событие ConsoleEvents::TERMINATE

Типичное назначение: Выполнит некоторые очищающие действия после выполнения команды.

После выполнени команды, вызывается событие ConsoleEvents::TERMINATE. Оно может быть использовано для выполнения любых действий, необходимых для всех команд, или для уборки того, что вы начали в слушателе ConsoleEvents::COMMAND (вроде отправки логов, закрытия соединения БД, отправки электронных писем, ...). Слушатель также может изменить код завершения.

Слушатели получают событие ConsoleTerminateEvent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\ConsoleEvents;

$dispatcher->addListener(ConsoleEvents::TERMINATE, function (ConsoleTerminateEvent $event) {
    // получает вывод
    $output = $event->getOutput();

    // получает выполненную команду
    $command = $event->getCommand();

    // отображает заданное содержание
    $output->writeln(sprintf('After running command <info>%s</info>', $command->getName()));

    // изменяет код завершения
    $event->setExitCode(128);
});

Tip

Это событие также выполняется когда команда вызывает исключение. Тогда оно выполняется прямо после события ConsoleEvents::ERROR. В этом случае, полученный код завершения является кодом исключения.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.