2015-07-20 38 views
2

調度一個簡單的事件中的Symfony 2Symfony的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,回到事件中去獲得我的修改實體。

回答

5

在PHP中,默認情況下所有對象都通過引用傳遞(http://php.net/manual/en/language.oop5.references.php)。所以在Symfony的代碼中沒有魔法。

這基本上是你做什麼:

  • 創建對象($document = new \Namespace\Document();

  • 通是參照事件的構造函數($event = new MyDocumentEvent($document);

  • 當事件被調度打電話吸氣劑返回參考 您的對象(return $this->document;

  • 那麼你修改對象($document->setLabel("This makes me crazy!");

  • 通過訪問對象使用相同的參考,看看 已經改變了對象。
+0

我確定沒有魔法。這是如何解釋這種行爲的? –

+0

我已經添加了一些說明。 – Mantas

+0

還不清楚。文檔變量永遠不會傳回給事件。您可以在MyListener中寫入$ aaa而不是$ document,它仍然會給出相同的結果......所以不是這樣。 –