Symfony控制台:事件未触发

问题描述 投票:1回答:1

these instructions之后,我使用以下命令安装了Symfony 3.4。

composer.phar create-project symfony/framework-standard-edition my_project_name_3_4

然后,在these other instructions之后,我向stock控制台应用程序添加了一个事件调度程序,以及一个事件监听器

#File: my_project_name_3_4/bin/console
/* ... other code ... */

$application = new Application($kernel);

//START: my new code

//create dispatcher and add to application
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
$application->setDispatcher($dispatcher);

//add my event to dispatcher
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\ConsoleEvents;

$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) {
    exit("\n\nHey, Symfony called my event!  Let's crash this party! \n\n");
});

//END:   my new code
$application->run($input);

但是,当我运行Symfony控制台命令时,

php bin/console help

我的事件不会发生。当Symfony调用我的ConsoleEvents::COMMAND监听器时,我希望上面的代码停止。

我做了一些调试,似乎调用$application->run从调度程序中删除了我的事件?!在我进行适当调试的兔子洞之前,我想检查并查看是否有任何明显我做错了,如果有已知的科学来解决这个问题。是否有不同的方式我应该将事件添加到库存Symfony控制台应用程序?

php symfony symfony-console
1个回答
1
投票

我猜我应该更仔细地阅读这个问题。一直到最后。我有点注意如何修改bin / console。

无论如何(双关语)你可以像add any event listener一样添加一个命令监听器。

namespace AppBundle;

use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class MySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        // return the subscribed events, their methods and priorities
        return array(
            ConsoleEvents::COMMAND => array(
                array('onCommand', 0),
            )
        );
    }
    public function onCommand(ConsoleCommandEvent $event)
    {
        echo "onCommand\n";
    }
}

由于默认的自动装配和自动配置,您甚至不必向services.yml添加任何内容。它只是有效。

=============================

原始答案

我想你可能会将控制台组件与控制台框架文档混为一谈。

首先通过编辑框架安装的bin / console文件来回答您的问题:

# bin/console
use Symfony\Bundle\FrameworkBundle\Console\Application as FrameworkApplication;
$kernel = new AppKernel($env, $debug);
$kernel->boot();

$application = new FrameworkApplication($kernel);

$dispatcher = $kernel->getContainer()->get('event_dispatcher');

$dispatcher->addListener(\Symfony\Component\Console\ConsoleEvents::COMMAND,
    function (\Symfony\Component\Console\Event\ConsoleCommandEvent $event) {
    exit("\n\nHey, Symfony called my event!  Let's crash this party! \n\n");
});
$application->run($input);

它是基于使用框架Application类的完全有效的代码。

但是,问题中的第二个链接指向基于组件应用程序类的控制台组件文档。

use Symfony\Component\Console\Application as ComponentApplication;

ComponentApplication类不了解内核或容器。它几乎是独立的,并提供了通过ComponentApplication :: setDispatcher注入事件调度程序的方法。如果您使用ComponentApplication类,那么您在问题中尝试的代码可以正常工作,但您必须注册自己的命令。

FrameworkApplication从内核中提取容器,然后从中提取事件调度程序并将其传递给setDispatcher。它还使用内核来注册命令。该类中的任何内容实际上都不依赖于未引导的内核。内核类本身可以防止多次启动。

因此,在调用FrameworkApplication :: run()之前启动内核并访问容器是可以的。

我想如果你真的想以“非脏”的方式做这件事,那么只需扩展Application类并在doRun方法中添加你的监听器。

© www.soinside.com 2019 - 2024. All rights reserved.