Я вижу, что новыми запланированными функциями для PHP 5.4 являются: черты, разнесение массивов, интерфейс JsonSerializable и что-то называемое « closure $this support
»,
http://en.wikipedia.org/wiki/Php#Release_history
В то время как остальные либо сразу очищаются (JsonSerialiable, разыменование массива), либо я искал специфику (черты), я не уверен, что такое «закрытие $ этой поддержки». Я был безуспешным поиском для него или нашел что-нибудь об этом на php.net
Кто-нибудь знает, что это должно быть?
Если бы я должен был догадаться, это означало бы что-то вроде этого:
$a = 10; $b = 'strrrring'; //'old' way, PHP 5.3.x $myClosure = function($x) use($a,$b) { if (strlen($x) <= $a) return $x; else return $b; }; //'new' way with closure $this for PHP 5.4 $myNewClosure = function($x) use($a as $lengthCap,$b as $alternative) { if(strlen($x) <= $this->lengthCap)) return $x; else { $this->lengthCap++; //lengthcap is incremented for next time around return $this->alternative; } };
Значение (даже если этот пример тривиально) заключается в том, что в прошлом, когда замыкание строится, фиксированные переменные «use» фиксированы. С «закрытием $ этой поддержки» они больше похожи на членов, с которыми вы можете столкнуться.
Является ли это правильным и / или близким и / или разумным? Кто-нибудь знает, что означает это «закрытие $ этой поддержки»?
Это уже было запланировано для PHP 5.3, но
Для PHP 5.3 $ эта поддержка Closures была удалена, потому что не удалось достичь консенсуса о том, как реализовать ее разумно. Этот RFC описывает возможные пути, которые можно использовать для реализации в следующей версии PHP.
Это действительно означает, что вы можете ссылаться на экземпляр объекта ( live demo )
<?php class A { private $value = 1; public function getClosure() { return function() { return $this->value; }; } } $a = new A; $fn = $a->getClosure(); echo $fn(); // 1
Для обсуждения см. PHP Wiki
и для исторического интереса:
Одна вещь, которую пропустил Гордон, – это перевязка $this
. Хотя то, что он описал, является поведением по умолчанию, его можно повторно связать.
пример
class A { public $foo = 'foo'; private $bar = 'bar'; public function getClosure() { return function ($prop) { return $this->$prop; }; } } class B { public $foo = 'baz'; private $bar = 'bazinga'; } $a = new A(); $f = $a->getClosure(); var_dump($f('foo')); // prints foo var_dump($f('bar')); // works! prints bar $b = new B(); $f2 = $f->bindTo($b); var_dump($f2('foo')); // prints baz var_dump($f2('bar')); // error $f3 = $f->bindTo($b, $b); var_dump($f3('bar')); // works! prints bazinga
bindTo
экземпляров bindTo
instance (альтернативно использует статическое Closure::bind
) вернет новое закрытие с $this
будет привязано к указанному значению. Объем задается путем передачи второго аргумента, это будет определять видимость частных и защищенных членов при доступе из-за закрытия.
Основываясь на ответе @ Gordon, можно подражать некоторым хакерским аспектам закрытия – $ this в PHP 5.3.
<?php class A { public $value = 12; public function getClosure() { $self = $this; return function() use($self) { return $self->value; }; } } $a = new A; $fn = $a->getClosure(); echo $fn(); // 12
Просто опираясь на другие ответы здесь, я думаю, что этот пример продемонстрирует, что возможно PHP 5.4+:
<?php class Mailer { public $publicVar = 'Goodbye '; protected $protectedVar = 'Josie '; private $privateVar = 'I love CORNFLAKES'; public function mail($t, $closure) { var_dump($t, $closure()); } } class SendsMail { public $publicVar = 'Hello '; protected $protectedVar = 'Martin '; private $privateVar = 'I love EGGS'; public function aMailingMethod() { $mailer = new Mailer(); $mailer->mail( $this->publicVar . $this->protectedVar . $this->privateVar, function() { return $this->publicVar . $this->protectedVar . $this->privateVar; } ); } } $sendsMail = new SendsMail(); $sendsMail->aMailingMethod(); // prints: // string(24) "Hello Martin I love EGGS" // string(24) "Hello Martin I love EGGS"