2024 日本 PHP 研討會

Closure::bind

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

Closure::bind 複製一個閉包,並綁定特定的物件和類別範圍

說明

公開 靜態 Closure::bind(Closure $closure, ?物件 $newThis, 物件|字串|null $newScope = "static"): ?Closure

這個方法是 Closure::bindTo() 的靜態版本。更多資訊請參考該方法的說明文件。

參數

closure

要綁定的匿名函式。

newThis

給定的匿名函式要綁定的物件,或是 null 表示解除閉包的綁定。

newScope

閉包要關聯的類別範圍,或是 'static' 表示維持目前的範圍。如果給定一個物件,則會使用該物件的類型。這決定了綁定物件的 protected 和 private 方法的能見度。不允許傳遞內部類別(的物件)作為此參數。

回傳值

回傳一個新的 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('第二個參數必須是可呼叫的');
}
$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('沒有指定名稱的方法可以呼叫');
}

}
?>

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
10 年前
如果您需要驗證一個閉包是否可以綁定到一個 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