The PHP manual offers little explanation about Closure::bind() and the example was confusing too.
Here's the code example on the site:
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";
What are the parameters for Closure::bind()?
Null was used in the above, and even the "new" keyword was used too, which makes this even more confusing to me.
If you put the value of $cl2
as a method of class A
, the class looks like this:
class A {
public $ifoo = 2;
function cl2()
{
return $this->ifoo;
}
}
and you can use it like this:
$x = new A();
$x->cl2();
# it prints
2
But, because $cl2
is a closure and not a member of class A
, the usage code above does not work.
The method Closure::bindTo()
allows using the closure as it were a method of class A
:
$cl2 = function() {
return $this->ifoo;
};
$x = new A();
$cl3 = $cl2->bindTo($x);
echo $cl3();
# it prints 2
$x->ifoo = 4;
echo $cl3();
# it prints 4 now
The closure uses the value of $this
but $this
is not defined in $cl2
. When $cl2()
runs, $this
is NULL
and it triggers an error ( "PHP Fatal error: Using $this
when not in object context" ).
Closure::bindTo()
creates a new closure but it "binds" the value of $this
inside this new closure to the object it receives as its first argument.
Inside the code stored in $cl3
, $this
has the same value as the global variable $x
. When $cl3()
runs, $this->ifoo
is the value of ifoo
in object $x
.
Closure::bind()
is the static version of Closure::bindTo()
. It has the same behaviour as Closure::bindTo()
but requires an additional argument: the first argument must be the closure to bind.
If you prefer to use static version, just try to
$cl4 = Closure::bind(function () { return $this->ifoo; }, new A(), 'A');
echo $cl4();
// it returns "2"
It is pretty cool, if you wanna update the property of an object, but there is no 'setter' for the property. For example:
class Product {
private $name;
private $local;
public function __construct(string $name) {
$this->name = $name;
$this->local = 'usa':
}
}
$product1 = new Product('nice product');
echo $product1->local;
// it returns 'usa'
$product2 = \Closure::bind(function () {
$this->local = 'germany';
return $this;
}, new Product('nice product'), 'Product');
echo $product2->local;
// it returns 'germany'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.