We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Issue with adding new events to the dispatcher event manager

I seem to have an issue with adding events to an event manager that was previous defined.

In the bootstrap I set the dispatcher like this

      $di->set( 'dispatcher', function()
      {
        // Create a new dispatcher
        $dispatcher = new Dispatcher();
        $dispatcher->setDefaultNamespace( '\\Controllers' );

        // Create an EventsManager
        $eventsManager =new EventsManager();

        // Bind the EventsManager to the dispatcher
        $dispatcher->setEventsManager( $eventsManager );

        return $dispatcher;
      });

A little further down in the bootstrap process I add modules to the project. These modules are initiated with an init.php that sets stuff up for the module itself.

In the users module I defined a few events in the init.php that need to be fire when certain conditions occur. See below for the simplified events.

      /** @var Dispatcher $dispatcher */
      $dispatcher =$di->getDispatcher();

      // Get the current manager
      $manager =$dispatcher->getEventsManager();

      var_dump( $manager );  // displays a manager withour any events in it

      $manager->attach( 'dispatch:afterDispatch',
        function( Event $event, Dispatcher $dispatcher ) use ( $di )
        {
          echo "dispatch:afterDispatch";
        }
      );

      $manager->attach( 'dispatch:beforeExecuteRoute',
        function( Event $event, Dispatcher $dispatcher ) use ( $di )
        {
          echo "dispatch:beforeExecuteRoute";
        }
      );

      var_dump( $manager );  // This displays the above two events in the manager. so far so good

      $di->getDispatcher()->setEventsManager( $manager );  // sets the manager back with the two events in it

      var_dump( $di->getDispatcher()->getEventsManager());  // shows a manager without any events in it
      exit;

With the last 3 lines I set an event manager with 2 events in it, but when I retrieve the manager again it is again empty like nothing was set.

It seems that I'am unable to set/change the event manager for the dispachter from another location then the initial definition. Which is strange as my code was working without issues on phalcon 3.4. but not on 4.0.

Anyone know what I might be doing incorrect. The events are working when I define them in the initial set-up, but not when I get the manager from the dispatcher, attach a few events to it and then set it again.

below the output from the var_dumps in the code block above. The First is the manager from the initial dispacher set-up. The second is the same manager with two events attached to it which should be stored via the set function. An the last should be the same as the second block, but instead it seems to be the same as the first dump.

/var/www/phalcon.test/web/backend/modules/Users/Init.php:30:
object(Phalcon\Events\Manager)[76]
  protected 'collect' => boolean false
  protected 'enablePriorities' => boolean false
  protected 'events' => null
  protected 'responses' => null

/var/www/phalcon.test/web/backend/modules/Users/Init.php:83:
object(Phalcon\Events\Manager)[76]
  protected 'collect' => boolean false
  protected 'enablePriorities' => boolean false
  protected 'events' => 
    array (size=2)
      'dispatch:afterDispatch' => 
        object(SplPriorityQueue)[75]
          private 'flags' => int 1
          private 'isCorrupted' => boolean false
          private 'heap' => 
            array (size=1)
              ...
      'dispatch:beforeExecuteRoute' => 
        object(SplPriorityQueue)[73]
          private 'flags' => int 1
          private 'isCorrupted' => boolean false
          private 'heap' => 
            array (size=1)
              ...
  protected 'responses' => null

/var/www/phalcon.test/web/backend/modules/Users/Init.php:87:
object(Phalcon\Events\Manager)[72]
  protected 'collect' => boolean false
  protected 'enablePriorities' => boolean false
  protected 'events' => null
  protected 'responses' => null


4.5k
edited Nov '20

According to the .zep file the internal variable eventmanager is protected and the get/set function just sets and gets the variable. No processing is done to the object.

So this should set the manager

$di->getDispatcher()->setEventsManager( $manager )

and this should retrieve the exact same manager as set before

$di->getDispatcher()->getEventsManager()

and yet the get returns the manager that is set in the initial set-up instead of the one that I just set with the set function



125.7k
Accepted
answer
edited Nov '20

I think the issue might be the dispatcher is set() rather than setShared(). Currently, every time you getDispatcher(), you're getting a new instance of Dispatcher. If you set it with setShared(), getDispatcher() will return a singleton instead.

Also, I added syntax highlighting to some of your code blocks. Simply adding php (or whatever language you want) after the three backticks will cause the code block to be highlighted.



4.5k

You are right. Strange that I missed that. I have all the other services set to shared. Code is working now. Thanks