有没有办法将$this
绑定到作为参数传递的闭包?
我阅读并重读了我在手册或互联网上找到的所有内容,但没有人提到这种行为,除了这篇博文:
http://www.christophh.net/2011/10/26/closure-object-binding-in-php-54/
提到它但没有说明如何做到这一点。
所以这是一个例子。在调用get(function() {})
方法时,我希望传递给它的回调函数绑定到对象,即绑定到$this
,但遗憾的是它不起作用。我有什么方法可以做到吗?
class APP
{
public $var = 25;
public function __construct() {
}
public function get($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Paran must be callable.');
}
// $callback->bindTo($this);
$callback->bindTo($this, $this);
$callback();
}
}
$app = new APP();
$app->get(function() use ($app) {
echo '<pre>';
var_dump($app);
echo '<br />';
var_dump($this);
});
$app
有效。 $this
为NULL。
答案 0 :(得分:8)
我实际上不明白为什么使用bindTo
方法在这种情况下不起作用,但我可以使用Closure::bind
public function get($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Param must be callable.');
}
$bound = Closure::bind($callback, $this);
$bound();
}
修改强>
显然bindTo
方法具有相同的行为,因此您应该将其返回值重新分配给$callback
。例如:
public function get($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Param must be callable.');
}
$callback = $callback->bindTo($this);
$callback();
}
答案 1 :(得分:3)
这样做:
class APP
{
public $var = 25;
public function __construct() {}
public function get($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Param must be callable.');
}
// $callback->bindTo($this);
// you must save result in another var and call it
$callback1 = $callback->bindTo($this, $this);
$callback1();
}
}
$app = new APP();
$app->get(function() use ($app) {
echo '<pre>';
var_dump($app);
echo '<br />';
var_dump($this);
});
答案 2 :(得分:1)
将其作为参数传递:
public function get($callback) {
if (!is_callable($callback)) {
throw new InvalidArgumentException('Paran must be callable.');
}
// $callback->bindTo($this);
return $callback($this);
}
...
$app = new APP();
$app->get(function($that) use ($app) {
echo '<pre>';
var_dump($app);
echo '<br />';
var_dump($that);
});
或者,如果您确实需要绑定它,则必须使用返回函数的函数,如下所示:
public function getCallback($callback) {
return function($app){
return $callback($this, $app);
}
}
...
$app = new APP();
$f = $app->get(function($that, $app) {
echo '<pre>';
var_dump($app);
echo '<br />';
var_dump($that);
});
$f($app);
答案 3 :(得分:1)
小修正:请勿使用is_callable
检查参数是否传递Closure
。
因为is_callable
也接受名称为function的String。
public function get(\Closure $callback) {
$bound = \Closure::bind($callback, $this);
$bound();
}
is_callable
我们有这种可能性:
$app = new App;
$app->get('my_function');
如果存在函数,则抛出此错误:
Closure :: bind()期望参数1为Closure,字符串为
因为&#34; My_function&#34;在is_callable
的测试中通过,但Closure::bind
期望Closure
的实例。