Je vois que les nouvelles fonctionnalités prévues pour PHP 5.4 sont: les traits, le déréférencement de tableaux, une interface JsonSerializable et quelque chose appelé 'closure $this support
'
http://en.wikipedia.org/wiki/Php#Release_history
Alors que les autres sont soit immédiatement clairs (JsonSerialiable, déréférencement de tableau) ou j'ai recherché les spécificités (traits), je ne suis pas sûr de ce qu'est la "fermeture de ce support". J'ai échoué sur Google ou trouvé quelque chose à ce sujet sur php.net
Quelqu'un sait-il ce que c'est censé être?
Si je devais deviner, cela signifierait quelque chose comme ceci:
$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;
}
};
La signification (même si cet exemple est trivial) est que dans le passé, une fois la fermeture construite, les variables liées à l'utilisation sont fixées. Avec "fermeture $ ce support", ils ressemblent plus à des membres avec lesquels vous pouvez jouer.
Ce son est-il correct et/ou proche et/ou raisonnable? Est-ce que quelqu'un sait ce que signifie cette "fermeture $ ce soutien"?
Cela était déjà prévu pour PHP 5.3, mais
Pour PHP 5.3 $, cette prise en charge des fermetures a été supprimée car aucun consensus n'a pu être atteint sur la façon de l'implémenter de manière saine. Ce RFC décrit les routes possibles qui peuvent être prises pour l'implémenter dans le prochain PHP version.
Cela signifie en effet que vous pouvez vous référer à l'instance d'objet ( démo en direct )
<?php
class A {
private $value = 1;
public function getClosure()
{
return function() { return $this->value; };
}
}
$a = new A;
$fn = $a->getClosure();
echo $fn(); // 1
Pour une discussion, voir le PHP Wiki
et pour un intérêt historique:
Une chose que Gordon a ratée est la reliure de $this
. Bien que ce qu'il ait décrit soit le comportement par défaut, il est possible de le lier à nouveau.
Exemple
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
Les fermetures bindTo
méthode d'instance (utilisez alternativement la statique Closure::bind
) renverra une nouvelle fermeture avec $this
re-lié à la valeur donnée. La portée est définie en passant le deuxième argument, cela déterminera la visibilité des membres privés et protégés, lorsqu'ils sont accessibles depuis l'intérieur de la fermeture.
En s'appuyant sur la réponse de @ Gordon, il est possible d'imiter certains aspects hacky de la fermeture - $ this en 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
Sur la base des autres réponses ici, je pense que cet exemple montrera ce qui est possible 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"