Dutch PHP Conference 2027

Closure::bind

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

Closure::bind バインドされたオブジェクトとクラスのスコープでクロージャを複製する

説明

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

このメソッドは、staticメソッド版の Closure::bindTo() です。 詳細な説明は Closure::bindTo() のドキュメントを参照ください。

パラメータ

closure

バインドする無名関数。

newThis

指定した無名関数をバインドするオブジェクト。クロージャのバインドを解除するには null を指定します。

newScope

クロージャを関連づけるクラススコープ、あるいは 'static' で現在のスコープを維持します。 オブジェクトを渡した場合は、そのオブジェクトの型をその代わりに使います。 これは、バインドしたオブジェクトの protected メソッドや private メソッドのアクセス権を決めます。 このパラメータに、内部クラスのオブジェクトを渡すことはできません。

戻り値

新しい Closure オブジェクトを返します。 失敗した場合は null を返します。

変更履歴

バージョン 説明
8.5.0 インスタンスを static なクロージャにバインドすることや、 互換性のないクラス階層間でメソッドをバインドすることは、非推奨になりました (これらの場合は、既に E_WARNING が発生していました)。

例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

参考

add a note

User Contributed Notes 2 notes

up
99
Vincius Krolow
13 years ago
With this class and method, it's possible to do nice things, like add methods on the fly to an object.

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

?>
up
11
potherca at hotmail dot com
11 years ago
If you need to validate whether or not a closure can be bound to a PHP object, you will have to resort to using reflection.

<?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