如何调用其他命令
如果一个命令依赖于另一个命令在其之前运行,您可以在控制台命令本身中调用它。如果您想创建一个“元”命令来运行一堆其他命令(例如,当项目代码在生产服务器上更改时需要运行的所有命令:清除缓存,生成 Doctrine 代理,导出 web 资源,...),这将非常有用。
使用 doRun()。然后,创建一个新的 ArrayInput,其中包含您要传递给命令的参数和选项。命令名称必须是第一个参数。
最终,调用 doRun()
方法实际上会运行命令并返回命令的返回代码(来自命令 execute()
方法的返回值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
// ...
use Symfony\Component\Console\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class CreateUserCommand extends Command
{
// ...
protected function execute(InputInterface $input, OutputInterface $output): int
{
$greetInput = new ArrayInput([
// the command name is passed as first argument
'command' => 'demo:greet',
'name' => 'Fabien',
'--yell' => true,
]);
// disable interactive behavior for the greet command
$greetInput->setInteractive(false);
$returnCode = $this->getApplication()->doRun($greetInput, $output);
// ...
}
}
提示
如果您想禁止执行命令的输出,请将 NullOutput 作为第二个参数传递给 $application->doRun()
。
注意
使用 doRun()
而不是 run()
可以防止自动退出,并允许返回退出代码。
此外,使用 $this->getApplication()->doRun()
而不是 $this->getApplication()->find('demo:greet')->run()
将允许为该内部命令正确地分发事件。
警告
请注意,所有命令将在同一进程中运行,并且某些 Symfony 的内置命令可能无法以这种方式良好地工作。例如,cache:clear
和 cache:warmup
命令会更改一些类定义,因此在它们之后运行某些内容可能会中断。
注意
大多数时候,从不在命令行上执行的代码中调用命令不是一个好主意。主要原因是命令的输出是为控制台优化的,而不是传递给其他命令。