Symfony命令根据参数添加选项

时间:2017-08-26 10:37:55

标签: symfony symfony-3.2

我想根据我的import命令中的参数添加选项。我认为可以在interact()中添加这些,但是当我运行

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

我得到了

  

[Symfony的\元器件\控制台\异常\的RuntimeException]
    “ - 供应商”选项不存在。

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

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'");
    }
}

2 个答案:

答案 0 :(得分:0)

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()));
}
}

答案 1 :(得分:0)

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

溶液 - 复制类Command将其声明为abstract,并让它扩展旧的Command - 复制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是&#39; 5&#39;