概述 快速入门 教程 手册 最佳实践 组件 参考 贡献

发布于 2015-08-27 16:48:28 | 128 次阅读 | 评论: 0 | 来源: 网络整理

By default, Symfony will take a look in the Command directory of each bundle and automatically register your commands. If a command extends the ContainerAwareCommand, Symfony will even inject the container. While making life easier, this has some limitations:

  • Your command must live in the Command directory;
  • There’s no way to conditionally register your service based on the environment or availability of some dependencies;
  • You can’t access the container in the configure() method (because setContainer hasn’t been called yet);
  • You can’t use the same class to create many commands (i.e. each with different configuration).

To solve these problems, you can register your command as a service and tag it with console.command:

  • YAML
    # app/config/config.yml
    services:
        acme_hello.command.my_command:
            class: AcmeHelloBundleCommandMyCommand
            tags:
                -  { name: console.command }
    
  • XML
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    
        <services>
            <service id="acme_hello.command.my_command"
                class="AcmeHelloBundleCommandMyCommand">
                <tag name="console.command" />
            </service>
        </services>
    </container>
    
  • PHP
    // app/config/config.php
    $container
        ->register('acme_hello.command.my_command', 'AcmeHelloBundleCommandMyCommand')
        ->addTag('console.command')
    ;
    

Using Dependencies and Parameters to Set Default Values for Options

Imagine you want to provide a default value for the name option. You could pass one of the following as the 5th argument of addOption():

  • a hardcoded string;
  • a container parameter (e.g. something from parameters.yml);
  • a value computed by a service (e.g. a repository).

By extending ContainerAwareCommand, only the first is possible, because you can’t access the container inside the configure() method. Instead, inject any parameter or service you need into the constructor. For example, suppose you have some NameRepository service that you’ll use to get your default value:

// src/Acme/DemoBundle/Command/GreetCommand.php
namespace AcmeDemoBundleCommand;

use AcmeDemoBundleEntityNameRepository;
use SymfonyComponentConsoleCommandCommand;
use SymfonyComponentConsoleInputInputInterface;
use SymfonyComponentConsoleInputInputOption;
use SymfonyComponentConsoleOutputOutputInterface;

class GreetCommand extends Command
{
    protected $nameRepository;

    public function __construct(NameRepository $nameRepository)
    {
        $this->nameRepository = $nameRepository;

        parent::__construct();
    }

    protected function configure()
    {
        $defaultName = $this->nameRepository->findLastOne();

        $this
            ->setName('demo:greet')
            ->setDescription('Greet someone')
            ->addOption('name', '-n', InputOption::VALUE_REQUIRED, 'Who do you want to greet?', $defaultName)
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $name = $input->getOption('name');

        $output->writeln($name);
    }
}

Now, just update the arguments of your service configuration like normal to inject the NameRepository. Great, you now have a dynamic default value!

警告

Be careful not to actually do any work in configure (e.g. make database queries), as your code will be run, even if you’re using the console to execute a different command.

最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务