symfony – 如何从console参数设置配置参数?

我是Symfony的新手.

我试图通过控制台参数’format = json’来改变Monolog输出格式化程序.

简而言之,我想用这样的方式运行任何控制台命令:

app/console my_command --format=json # xml / txt / my own

…以请求的格式获取LoggerInterface的输出.

例如,我在配置中设置了默认格式化程序:

monolog:
    handlers:
        console:
            type:   console
            channels: [!event, !doctrine]
            formatter: json_formatter
services:
    json_formatter:
        class: Monolog\Formatter\JsonFormatter

当我创建一些MyEventListener :: onConsoleCommand(as described here)时,我无法更改参数包,因为它已经被编译:“无法在冻结的ParameterBag上调用set().”

Up2:在这种情况下我的服务配置如下所示:

services:
    kernel.listener.command_dispatch:
        class: My\Listener\MyEventListener
        autowire: true
        tags:
            - { name: kernel.event_listener, event: console.command }

换句话说,我可以在初始文件中注册控制台选项:

# app/console
$loader = require __DIR__.'/autoload.php';
# ...
$application->getDefinition()->addOption(
    new InputOption(
        'formatter',
        'f',
        InputOption::VALUE_OPTIONAL,
        'The logs output formatter',
        'json_formatter'
    )
);

但是我找不到在Container中更改参数包的方法.因为$application-> getKernel() – > getContainer()仍为空.

那么,如何从控制台输入中更改Symfony2参数?

或者,也许我可以使用一些环境参数?但是如何在YAML配置中获取环境变量?

谢谢.

UP3:
我用这样的环境变量实现了目标:

SYMFONY__LOG__FORMATTER=json_formatter app/console my_command
monolog:
    handlers:
        console:
            type: console
            #...
            formatter: '%log.formatter%'

最佳答案 修改应用程序的每个已注册命令的命令参数的唯一一点是处理在执行任何命令之前触发的CommandEvents :: COMMAND.因此,您可以修改其参数并按照
here所述读取它们.此外,此时您已编译容器,此时无法修改服务的定义.但是你可以获得任何服务.

所以我认为你最终可以得到以下处理程序:

class LogFormatterEventListener
{
    private $container;
    private $consoleHandler;

    public function __construct(ContainerInterface $container, HandlerInterface $consoleHandler)
    {
        $this->container = $container;
        $this->consoleHandler = $consoleHandler;
    }

    public function onConsoleCommand(ConsoleCommandEvent $event)
    {
        $inputDefinition = $event->getCommand()->getApplication()->getDefinition();

        $inputDefinition->addOption(
            new InputOption('logformat', null, InputOption::VALUE_OPTIONAL, 'Format of your logs', null)
        );

        // merge the application's input definition
        $event->getCommand()->mergeApplicationDefinition();

        $input = new ArgvInput();

        // we use the input definition of the command
        $input->bind($event->getCommand()->getDefinition());

        $formatter = $input->getOption('logformat');
        if ($formatter /** && $this->container->has($formatter) **/) {
            $this->consoleHandler->setFormatter(
                $this->container->get($formatter);
            );
        }
    }
}
点赞