Closure::bind

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

Closure::bind复制一个闭包,并指定绑定的对象和类作用域

描述

public static Closure::bind(Closure $closure, ?object $newThis, object|string|null $newScope = "static"): ?Closure

此方法是 Closure::bindTo() 的静态版本。有关更多信息,请参阅该方法的文档。

参数

closure

要绑定的匿名函数。

newThis

要将给定匿名函数绑定到的对象,或 **null** 用于将闭包解除绑定。

newScope

要将闭包关联到的类作用域,或 'static' 以保留当前作用域。如果给定对象,则将使用对象的类型。这决定了绑定对象受保护和私有方法的可见性。不允许将(内部类的)对象传递为此参数。

返回值

返回一个新的 Closure 对象,或在失败时返回 **null**。

示例

示例 #1 Closure::bind() 示例

<?php
class A {
private static
$sfoo = 1;
private
$ifoo = 2;
}
$cl1 = static function() {
return
A::$sfoo;
};
$cl2 = function() {
return
$this->ifoo;
};

$bcl1 = Closure::bind($cl1, null, 'A');
$bcl2 = Closure::bind($cl2, new A(), 'A');
echo
$bcl1(), "\n";
echo
$bcl2(), "\n";
?>

上面的示例将输出类似于以下内容

1
2

参见

添加备注

用户贡献的备注 2 个备注

Vincius Krolow
11 年前
使用此类和方法,可以实现一些不错的事情,例如动态地向对象添加方法。

MetaTrait.php
<?php
trait MetaTrait
{

private
$methods = array();

public function
addMethod($methodName, $methodCallable)
{
if (!
is_callable($methodCallable)) {
throw new
InvalidArgumentException('Second param must be callable');
}
$this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class());
}

public function
__call($methodName, array $args)
{
if (isset(
$this->methods[$methodName])) {
return
call_user_func_array($this->methods[$methodName], $args);
}

throw
RunTimeException('There is no method with the given name to call');
}

}
?>

test.php
<?php
require 'MetaTrait.php';

class
HackThursday {
use
MetaTrait;

private
$dayOfWeek = 'Thursday';

}

$test = new HackThursday();
$test->addMethod('when', function () {
return
$this->dayOfWeek;
});

echo
$test->when();

?>
potherca at hotmail dot com
9 年前
如果您需要验证闭包是否可以绑定到 PHP 对象,则需要使用反射。

<?php

/**
* @param \Closure $callable
*
* @return bool
*/
function isBindable(\Closure $callable)
{
$bindable = false;

$reflectionFunction = new \ReflectionFunction($callable);
if (
$reflectionFunction->getClosureScopeClass() === null
|| $reflectionFunction->getClosureThis() !== null
) {
$bindable = true;
}

return
$bindable;
}
?>
To Top