Как передать параметры анонимным функциям в PHP?

У меня есть следующий кусок кода:

$evManager = $di->getShared('eventsManager');
$evManager->attach('dispatch', function($event, $dispatcher, $exception){
$dispatcher = new \Phalcon\Mvc\Dispatcher();
$dispatcher->setEventsManager($evManager);

return $dispatcher;
})

$ evManager — это объект, у которого есть метод attach, который принимает два аргумента, и для меня это понятно. Второй параметр — это анонимная функция, которая имеет три аргумента ($ event, $ dispatcher, $ exception).

Итак, мой вопрос: что это за три параметра? Почему они не пусты? Что они передают анонимной функции? Я не могу этого понять …

Я знаю, что анонимная функция возвращает объект диспетчера, а метод attach что-то делает с ним. Единственный вопрос о параметрах.

2

Решение

Думайте об этой анонимной функции как об обычном объекте с методом на нем. Вы можете написать этот код так:

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());

Так что теперь больше нет анонимной функции.
«Волшебство» происходит внутри $evManager->attach, Это определение выглядит примерно так:

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]);
}
}

Вы должны прочитать документы для call_user_func.

Теперь, если мы продолжим с моей «заменой анонимной функции примером класса», приведенный выше код будет выглядеть так:

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);
}
}

Это то, что делает анонимная функция.
Ваш код не имеет ничего общего с вызовом этой функции. Это не под вашим контролем, вы не можете сказать это какие параметры для вызова анонимной функции, вот что eventsManager делает.
Анонимная функция не называется, где вы определяете, и вы можете определить любой количество параметров на нем и назовите их как угодно.

Кроме того, код внутри анонимной функции может выглядеть так, как будто он делает что-то магическое в отношении кода вне ее, но это не. $dispatcher->setEventsManager($evManager) тоже неправильно, я не вижу global $evManager в любом месте.

4

Другие решения

Эти параметры обычно предоставляют дополнительную информацию при работе с подобной плагину архитектурой. Например, если у вас есть контейнер внедрения зависимостей, например

$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);
});

Тогда в некоторых случаях вам может потребоваться получить зависимость, а в некоторых случаях нет.

Как это устроено?
Это просто

Вы просто предполагаете, что параметр будет функцией, и поэтому передаете аргументы ему прямо при объявлении. Например, в том $di определение класса, это будет выглядеть так:

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)
}
}
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector