支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
Console组件中的Application类,令你能够可选地通过事件来打入到命令行程序的生命周期中。并非重复发明轮子,它使用了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(); |
命令行事件,仅在主力命令(main 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) {
// get the input instance / 取得input实例
$input = $event->getInput();
// get the output instance / 取得output实例
$output = $event->getOutput();
// get the command to be executed / 取得将要执行的命令
$command = $event->getCommand();
// write something about the command / 写入和命令有关的内容
$output->writeln(sprintf('Before running command <info>%s</info>', $command->getName()));
// get the application / 获取application
$application = $command->getApplication();
}); |
使用 disableCommand()
方法,你可以在监听中禁用命令。程序将 不再 执行命令,而是会返回 113
(定义在 ConsoleCommandEvent::RETURN_CODE_DISABLED
)。这个code是 reserved exit codes(保留退出码)中的一个,用于使控制台命令符合 C/C++ 标准:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\ConsoleEvents;
$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
// get the command to be executed / 取得将要执行的命令
$command = $event->getCommand();
// ... check if the command can be executed
// ... 检查命令是否可以被执行
// disable the command, this will result in the command being skipped
// and code 113 being returned from the Application
// 禁用命令,将导致命令被跳过,并从Application中返回113 code。
$event->disableCommand();
// it is possible to enable the command in a later listener
// 也可以在后面的监听中开启命令
if (!$event->commandShouldRun()) {
$event->enableCommand();
}
}); |
主要目的:在命令执行的过程中,处理“异常抛出”。
只要是在命令行中抛出异常,ConsoleEvents::EXCEPTION
事件就被派遣。监听器可以打包或改变此异常,或是在异常被程序抛出之前,做一些有用的事。
监听接收的是 ConsoleExceptionEvent
事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | use Symfony\Component\Console\Event\ConsoleExceptionEvent;
use Symfony\Component\Console\ConsoleEvents;
$dispatcher->addListener(ConsoleEvents::EXCEPTION, function (ConsoleExceptionEvent $event) {
$output = $event->getOutput();
$command = $event->getCommand();
$output->writeln(sprintf('Oops, exception thrown while running command <info>%s</info>', $command->getName()));
// get the current exit code (the exception code or the exit code set by a ConsoleEvents::TERMINATE event)
// 获取当前的退出码(异常代码或是退出码的设置,是通过ConsoleEvents::TERMINATE事件来完成)
$exitCode = $event->getExitCode();
// change the exception to another one / 把异常改为另一个
$event->setException(new \LogicException('Caught exception', $exitCode, $event->getException()));
}); |
主要目的:在命令执行完毕后,执行一些清场的动作。
在命令被执行之后,ConsoleEvents::TERMINATE
事件被派遣。它可用于为“所有命令”做任何“需要被执行”的操作,或者用于清除你在 ConsoleEvents::COMMAND
监听中所初始化的东西(比如发送日志,关闭数据库连接,发送邮件,...)。监听也可能会改变退出码(exit code)。
监听接收的是 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) {
// get the output / 获取output
$output = $event->getOutput();
// get the command that has been executed / 获取已被执行的命令
$command = $event->getCommand();
// display something / 显示内容
$output->writeln(sprintf('After running command <info>%s</info>', $command->getName()));
// change the exit code / 改变退出码
$event->setExitCode(128);
}); |
本事件也会在“有异常被命令抛出”的时候派遣。它是在 ConsoleEvents::EXCEPTION
事件之后被派遣。本例中的退出码就是异常代码(exception code)。
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。