Reputation: 228
I have the following piece of code:
$evManager = $di->getShared('eventsManager');
$evManager->attach('dispatch', function($event, $dispatcher, $exception){
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($evManager);
return $dispatcher;
})
$evManager is object that has a method called attach which takes two arguments and it's clear for me. The second parameter is an anonymous function which has three arguments ($event, $dispatcher, $exception).
So my question is what are these three parameters? Why they aren't empty? What pass they to the anonymous function? I can't understand it...
I know that the anonymous function returns dispatcher object and the method attach do something on it. The only question is about parameters.
Upvotes: 2
Views: 1956
Reputation: 10153
Think of that anonymous function as being an ordinary object with a method on it. You could write that code like this:
class MyDispatcherHelper {
public function handle($event, $dispatcher, $exception) {
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($evManager);
return $dispatcher;
}
}
$evManager = $di->getShared('eventsManager');
$evManager->attach('dispatch', new MyDispatcherHelper());
So now there's no more anonymous function.
The "magic" happens inside $evManager->attach
. It's definition looks something like this:
class EventsManager {
public function attach($eventName, $handler) {
// somehow listen for events named $eventName
...
// and get an instance of the Event
$myEvent = $listener->theEvent;
// if it's an exception maybe set $exception to something usefull?
...
//_call_ $handler when event occurs
call_user_func($handler, [$myEvent, $this, $exception]);
}
}
You should read the docs for call_user_func.
Now if we continue with my "replace anonymous function with class example" the above code would look like this:
class EventsManager {
public function attach($eventName, MyDispatcherHelper $handler) {
// somehow listen for events named $eventName
...
// and get an instance of the Event
$myEvent = $listener->theEvent;
// if it's an exception maybe set $exception to something usefull?
...
//_call_ $handler when event occurs
$handler->handle($myEvent, $this, $exception);
}
}
That's what an anonymous function does.
Your code has nothing to do with calling that function. It is not under your control, you cannot tell it what parameters to call the anonymous function with, that's what eventsManager
does.
An anonymous function is not called where you define it, and you can define any number of parameters on it and name them whatever you like.
Also the code inside the anonymous function might look like it does some magic regarding the code outside of it but it does not. $dispatcher->setEventsManager($evManager)
is also wrong, I'm not seeing a global
$evManager
anywhere.
Upvotes: 4
Reputation: 8701
Those parameters usually tend to provide some additional information when working with plugin-like architecture. For example, if you have a Dependency Injection container, like
$di->register('translator', function($di){
// You can omit usage of $di here, because you don't need to grab from the container at right now
return new Translator();
});
$di->register('Message', function($di){
$translator = $di->get('translator');
return new Message($translator);
});
Then in some cases you might need to grab a dependency, while in some cases you don't.
How it works? That's simple.
You simply assume that a parameter will be a function and therefore you pass arguments to it right at declaration. For example, in that $di
class definition, it would look like this:
class Di
{
public function register($name, $provider)
{
// We will assume that $provider is a function
// and therefore pass some data to it
$this->data[$name] => $provider($this); // or another parameter (s)
}
}
Upvotes: 2