You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Symfony命令中包装Drush并传递未解析参数

当然可以实现这个需求啦!其实不用折腾事件调度器去修改未解析的输入,Symfony Console(Drush和你的myapp大概率都是基于它开发的)本身就有现成的方案来处理这种场景,下面给你两种实用的方法:

方法一:使用贪婪参数(首推)

在你的MyAppDrushCommand类里定义命令时,把接收后续内容的参数设置为贪婪模式,它会自动把drush之后的所有内容(包括空格、短选项、长选项)都打包成数组(或者你可以转成字符串)传递给命令。

示例代码:

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

class MyAppDrushCommand extends Command
{
    protected static $defaultName = 'drush';

    protected function configure()
    {
        $this
            ->setDescription('A wrapper for running Drush commands via myapp')
            // 关键配置:IS_ARRAY + REMAINDER 让参数接收所有剩余输入
            ->addArgument(
                'drush_args',
                InputArgument::IS_ARRAY | InputArgument::REMAINDER,
                'All arguments, flags, and options to pass to Drush'
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $drushArgs = $input->getArgument('drush_args');
        
        // 直接用数组传给Process更安全,避免字符串转义问题
        $process = new Process(array_merge(['drush'], $drushArgs));
        $process->run();

        if (!$process->isSuccessful()) {
            $output->write($process->getErrorOutput());
            return Command::FAILURE;
        }

        $output->write($process->getOutput());
        return Command::SUCCESS;
    }
}

当用户输入myapp drush some drush arguments maybe a --flag-too时,drush_args会得到数组['some', 'drush', 'arguments', 'maybe', 'a', '--flag-too'],直接和drush合并后传给Process就行。如果确实需要完整字符串,用implode(' ', $drushArgs)就能得到你想要的内容。

方法二:直接获取原始输入(适合特殊场景)

如果你一定要拿到drush之后的原始未解析字符串,可以通过InputInterface的getRawInput()方法(Symfony Console 4.4及以上版本支持)来实现:

protected function execute(InputInterface $input, OutputInterface $output)
{
    // 获取完整的命令行原始输入
    $rawInput = $input->getRawInput();
    // 截取"drush"之后的部分,注意去掉开头的空格
    $drushCommandPart = ltrim(substr($rawInput, strpos($rawInput, 'drush') + 5));

    // 用shell命令行方式运行
    $process = Process::fromShellCommandline("drush $drushCommandPart");
    $process->run();

    // 后续的输出处理和方法一一致...
}

不过这种方法要注意边界情况(比如极端场景下输入里的drush可能是某个参数的一部分,但你的命令是myapp drush,这种概率极低),而且用fromShellCommandline存在潜在的shell注入风险,所以优先推荐方法一。

额外小贴士

如果你的myapp是基于Laravel Artisan开发的,完全不用担心,Artisan底层就是Symfony Console,上面的代码只需要把命令类继承Illuminate\Console\Command就能直接用。

内容的提问来源于stack exchange,提问作者Daniel Feder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:38:27