Hi
Even though one cannot bind a static closure to an instance, one can
rebind its scope with the Closure::bind/Closure::bindTo:
class foo {
static protected $field = "foo_field";
static function getClosure() {
return static function () {
//causes a crash (fbc already freed) in call after
rebinding,
//so let's not use it
//echo get_called_class(), "\n";
echo static::$field, "\n";
};
}
}
class subFoo {
static protected $field = "subfoo_field";
}
$c = foo::getClosure();
$c(); //foo_field
$c = $c->bindTo(new subFoo());
$c(); //subfoo_field
It doesn't make sense to require an instance in order to change the scope
of a static closure, so perhaps better options would be:
1. Change Closure::bind/Closure::bindTo so that they accept a class name
for static closures and an instance otherwise
2. Provide a method to change simultaneously the (calling) scope and the
called scope
3. Provide separate methods to change the called scope and the scope
I think either 2 or 3 would be better than 1 because the fact the
rebinding a closure changes its scope is not a great idea. Consider:
class foo {
private $field = "foo";
function getClosure() {
return function () {
echo $this->field, "\n";
};
}
}
class subFoo extends foo {}
$f = new subFoo();
$g = new subFoo();
$c = $f->getClosure();
$c(); //foo
$c = $c->bindTo($g); //or even $c->bindTo($f)
$c(); //fails
Thoughts?
--
Gustavo Lopes
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php