如何给PHP中的匿名函数传递参数?
How to pass parameters to anonymous functions in 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)。
所以我的问题是这三个参数是什么?为什么它们不是空的?什么将它们传递给匿名函数?看不懂...
我知道匿名函数 returns dispatcher 对象和方法 attach 对它做了一些事情。唯一的问题是关于参数。
将匿名函数想象成一个带有方法的普通对象。你可以这样写代码:
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());
所以现在没有更多的匿名函数了。
"magic" 发生在 $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 的文档。
现在,如果我们继续 "replace anonymous function with class example",上面的代码将如下所示:
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
所做的。
匿名函数 not 在你定义它的地方被调用,你可以在它上面定义 any 数量的参数并随意命名它们。
此外,匿名函数内部的代码可能看起来对外部代码有一些魔力,但它不是。 $dispatcher->setEventsManager($evManager)
也是错误的,我在任何地方都没有看到 global
$evManager
。
在使用类似插件的架构时,这些参数通常会提供一些额外的信息。例如,如果你有一个依赖注入容器,比如
$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 定义中,它看起来像这样:
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)
}
}
我有如下一段代码:
$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)。
所以我的问题是这三个参数是什么?为什么它们不是空的?什么将它们传递给匿名函数?看不懂...
我知道匿名函数 returns dispatcher 对象和方法 attach 对它做了一些事情。唯一的问题是关于参数。
将匿名函数想象成一个带有方法的普通对象。你可以这样写代码:
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());
所以现在没有更多的匿名函数了。
"magic" 发生在 $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 的文档。
现在,如果我们继续 "replace anonymous function with class example",上面的代码将如下所示:
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
所做的。
匿名函数 not 在你定义它的地方被调用,你可以在它上面定义 any 数量的参数并随意命名它们。
此外,匿名函数内部的代码可能看起来对外部代码有一些魔力,但它不是。 $dispatcher->setEventsManager($evManager)
也是错误的,我在任何地方都没有看到 global
$evManager
。
在使用类似插件的架构时,这些参数通常会提供一些额外的信息。例如,如果你有一个依赖注入容器,比如
$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 定义中,它看起来像这样:
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)
}
}