【问题标题】:Symfony command add option based on argumentSymfony 命令添加基于参数的选项
【发布时间】:2017-08-26 10:37:55
【问题描述】:

我想根据我的导入命令中的参数添加选项。我认为将这些添加到 interact() 中是可行的,但是当我运行时

bin/console app:import test --supplier=5

我明白了

[Symfony\Component\Console\Exception\RuntimeException]
“--supplier”选项不存在。

我知道我可以使用问题,但我更喜欢选项,因为这样可以减少定期运行导入命令的麻烦! 这是我的命令:

class ImportCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this
            ->setName('app:import')
            ->addArgument('importKey', InputArgument::REQUIRED)
        ;
    }

    protected function interact(InputInterface $input, OutputInterface $output)
    {
        $key = $input->getArgument('importKey');


        // this will be handled in
        // $importProvider = $this->getContainer()->get('app.import.provider');
        // $importer = $importProvider->getImport($key);
        // $importer->configureCommand($input, $output, $this);
        // but for simplicity's sake
        if($key == 'test')
        {
            $this->addOption('supplier', null,InputOption::VALUE_REQUIRED);
        }


    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {

        $supplier = $input->getOption('supplier');

        $output->writeln("your provided suplier id is '$supplier'");
    }
}

【问题讨论】:

    标签: symfony symfony-3.2


    【解决方案1】:

    symfony 可选参数命令

    <?php
     namespace sandboxBundle\Command;
    
     use Symfony\Component\Console\Command\Command;
     use Symfony\Component\Console\Input\InputInterface;
     use Symfony\Component\Console\Output\OutputInterface;
    
     // Add the required classes
     use Symfony\Component\Console\Input\InputDefinition;
     use Symfony\Component\Console\Input\InputOption;
    
    
     class TestCommand extends Command
      {
          protected function configure()
           {
            $this
               // the name of the command (the part after "bin/console")
              ->setName('app:print-lines')
               // the short description shown while running "php bin/console list"
             ->setHelp("This command allows you to print some text in the console")
             // the full command description shown when running the command with
             ->setDescription('Prints some text into the console with given parameters.')
            // Set options
              ->setDefinition(
                new InputDefinition(array(
                    new InputOption('firstline', 'a', InputOption::VALUE_REQUIRED,"The first line to be printed","Default First Line Value"),
                    new InputOption('secondline', 'b', InputOption::VALUE_OPTIONAL,"The second line to be printed","Default First Line Value"),
                ))
            )
        ;
    }
    
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        // outputs multiple lines to the console (adding "\n" at the end of each line)
        $output->writeln([
            'My Third Symfony command',// A line
            '============',// Another line
            '',// Empty line
        ]);
    
        $firstLine = $input->getOption('firstline');
        $secondline = $input->getOption('secondline');
    
        $output->writeln("First line value : ".$firstLine);
    
        if($secondline){
            $output->writeln("Second line value : ".$secondline);
        }
    
        // Instead of retrieve line per line every option, you can get an array of all the providen options :
        //$output->writeln(json_encode($input->getOptions()));
    }
    }
    

    【讨论】:

    • 这不符合我的要求,因为第一行和第二行是在 configure() 中定义的,我们不知道导入密钥。
    • 你可以试试 addArgument('supplier', InputArgument::OPTIONAL)
    • 这并没有改变任何东西,因为在输入绑定之后调用了 interact()...我想出了一个解决方案并现在发布...但是无论如何谢谢
    【解决方案2】:

    我找到了一个解决方案......很可能不是最好的,但它有效

    解决方案 - 复制类命令声明它抽象并让它扩展旧命令 - 复制 ContainerAwareCommand 并让它扩展你的新命令 - 将代码添加到新命令中

    public function notIgnoreValidationErrors()
    {
        $this->ignoreValidationErrors = false;
    }
    
    protected function configureAdditionalInput(InputInterface $input, OutputInterface $output)
    {
    }
    

    -将 run() 更改为

    public function run(InputInterface $input, OutputInterface $output)
    {
        // force the creation of the synopsis before the merge with the app definition
        $this->getSynopsis(true);
        $this->getSynopsis(false);
    
        // add the application arguments and options
        $this->mergeApplicationDefinition();
    
        // bind the input against the command specific arguments/options
        try {
            $input->bind($this->definition);
        } catch (ExceptionInterface $e) {
            if (!$this->ignoreValidationErrors) {
                throw $e;
            }
        }
    
        $this->configureAdditionalInput($input, $output);
    
        // bind the input against the command specific arguments/options
        try {
            $input->bind($this->definition);
        } catch (ExceptionInterface $e) {
            if (!$this->ignoreValidationErrors) {
                throw $e;
            }
        }
    
        $this->initialize($input, $output);
    
        if (null !== $this->processTitle) {
            if (function_exists('cli_set_process_title')) {
                if (false === @cli_set_process_title($this->processTitle)) {
                    if ('Darwin' === PHP_OS) {
                        $output->writeln('<comment>Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.</comment>');
                    } else {
                        $error = error_get_last();
                        trigger_error($error['message'], E_USER_WARNING);
                    }
                }
            } elseif (function_exists('setproctitle')) {
                setproctitle($this->processTitle);
            } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
                $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
            }
        }
    
        if ($input->isInteractive()) {
            $this->interact($input, $output);
        }
    
        // The command name argument is often omitted when a command is executed directly with its run() method.
        // It would fail the validation if we didn't make sure the command argument is present,
        // since it's required by the application.
        if ($input->hasArgument('command') && null === $input->getArgument('command')) {
            $input->setArgument('command', $this->getName());
        }
    
        $input->validate();
    
        if ($this->code) {
            $statusCode = call_user_func($this->code, $input, $output);
        } else {
            $statusCode = $this->execute($input, $output);
        }
    
        return is_numeric($statusCode) ? (int) $statusCode : 0;
    }
    

    - 将您的命令更改为(ContainerAwareCommand 是您的新类)

    class ImportCommand extends ContainerAwareCommand
    {
        protected function configure()
        {
            $this
                ->setName('app:import')
                ->addArgument('importKey', InputArgument::REQUIRED)
            ;
            $this->ignoreValidationErrors();
        }
    
        protected function configureAdditionalInput(InputInterface $input, OutputInterface $output)
        {
            $key = $input->getArgument('importKey');
    
            $this->notIgnoreValidationErrors();
    
            // this will be handled in
            // $importProvider = $this->getContainer()->get('app.import');
            // $importer = $importProvider->getImport($key);
            // $importer->configureCommand($input, $output, $this);
            if($key == 'test')
            {
                $this->addOption('supplier', null,InputOption::VALUE_REQUIRED);
            }
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
    
            $supplier = $input->getOption('supplier');
    
            $output->writeln("your provided suplier id is '$supplier'");
        }
    }
    

    现在运行命令

    bin/console app:import test --supplier=5
    

    您提供的供应商 ID 是“5”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-12
      • 2018-03-12
      • 2011-08-25
      • 1970-01-01
      相关资源
      最近更新 更多