Symfony 2 - 调度事件和全局变量的奇怪行为

时间:2015-07-20 13:56:23

标签: php symfony

调度插入Symfony 2中的简单侦听器的简单事件。

事件

class MyDocumentEvent extends Event {
    private $document;

    public function __construct(\Namespace\Document $document)
    {
        $this->document = $document;
    }

    public function getDocument()
    {
        return $this->document;
    }
}

监听

/**
 * @DI\Service("core.document.insert", public=true)
 * @DI\Tag("kernel.event_listener", attributes={"event"="document.insert.event", "method"="onEventReceived"})
 * NB This is equivalent to declaring a service in services.yml (DIExtraBundle is awesome by the way)
 */
class MyListener
{
    public function onEventReceived(MyDocumentEvent $event)
    {
        $document = $event->getDocument();
        // $aaa = $event->getDocument(); // is the same

        // perform stuff on $document or $aaa

        $document->setLabel("This makes me crazy!");
        // $aaa->setLabel(); // is the same
        return;
    }
}

非常奇怪的是,在我的控制器中,文档实体被神奇地修改,好像 $document是一个全局变量!

控制器测试代码

$dispatcher = $this->container->get('event_dispatcher');

$document = new \Namespace\Document();
$document->setLabel('unit.test.document.insert');

$event = new MyDocumentEvent($document);
$dispatcher->dispatch('document.insert.event', $event);

echo $document->getLabel(); // RETURNS "This makes me crazy!"

这真让我烦恼。为什么Symfony 2有这种行为?

这是正常现象还是我在这里犯了很大的建筑错误?我有点被怀疑我必须从听众中添加getter和setter回到事件来获取我修改过的实体。

1 个答案:

答案 0 :(得分:6)

在PHP中,默认情况下所有对象都通过引用传递(http://php.net/manual/en/language.oop5.references.php)。所以在Symfony的代码中没有任何魔力。

这基本上就是你做的事情:

  • 创建对象($document = new \Namespace\Document();

  • 传递它对事件构造函数的引用($event = new MyDocumentEvent($document);

  • 调度事件时,调用返回引用的getter 你的对象(return $this->document;

  • 然后修改对象($document->setLabel("This makes me crazy!");

  • 通过访问对象使用相同的引用并查看 已经改变了对象。