瀏覽代碼

[EventDispatcher] changed listener storage to use SplObjectStorage to avoid collisions

Fabien Potencier 14 年之前
父節點
當前提交
bd8d2b829f
共有 1 個文件被更改,包括 10 次插入9 次删除
  1. 10 9
      src/Symfony/Component/EventDispatcher/EventDispatcher.php

+ 10 - 9
src/Symfony/Component/EventDispatcher/EventDispatcher.php

@@ -77,7 +77,7 @@ class EventDispatcher implements EventDispatcherInterface
         }
 
         $sorted = array();
-        foreach ($this->listeners as $eventName => $listeners) {
+        foreach (array_keys($this->listeners) as $eventName) {
             if (!isset($this->sorted[$eventName])) {
                 $this->sortListeners($eventName);
             }
@@ -103,16 +103,15 @@ class EventDispatcher implements EventDispatcherInterface
      */
     public function addListener($eventNames, $listener, $priority = 0)
     {
-        $hash = spl_object_hash($listener);
         foreach ((array) $eventNames as $eventName) {
             if (!isset($this->listeners[$eventName][$priority])) {
                 if (!isset($this->listeners[$eventName])) {
                     $this->listeners[$eventName] = array();
                 }
-                $this->listeners[$eventName][$priority] = array();
+                $this->listeners[$eventName][$priority] = new \SplObjectStorage();
             }
 
-            $this->listeners[$eventName][$priority][$hash] = $listener;
+            $this->listeners[$eventName][$priority]->attach($listener);
             unset($this->sorted[$eventName]);
         }
     }
@@ -127,10 +126,9 @@ class EventDispatcher implements EventDispatcherInterface
                 continue;
             }
 
-            $hash = spl_object_hash($listener);
             foreach (array_keys($this->listeners[$eventName]) as $priority) {
-                if (isset($this->listeners[$eventName][$priority][$hash])) {
-                    unset($this->listeners[$eventName][$priority][$hash], $this->sorted[$eventName]);
+                if (isset($this->listeners[$eventName][$priority][$listener])) {
+                    unset($this->listeners[$eventName][$priority][$listener], $this->sorted[$eventName]);
                 }
             }
         }
@@ -180,10 +178,13 @@ class EventDispatcher implements EventDispatcherInterface
     private function sortListeners($eventName)
     {
         $this->sorted[$eventName] = array();
-
         if (isset($this->listeners[$eventName])) {
             krsort($this->listeners[$eventName]);
-            $this->sorted[$eventName] = array_values(call_user_func_array('array_merge', $this->listeners[$eventName]));
+            foreach ($this->listeners[$eventName] as $listeners) {
+                foreach ($listeners as $listener) {
+                    $this->sorted[$eventName][] = $listener;
+                }
+            }
         }
     }
 }