Bonjour à tous,
j'ai eu l'occasion de voir la commande suivante dans le framework php-fuel
public static function forge($param)
{
return new static($params);
}
Apparemment le new static fait appel au constructeur de la class.
Je ne comprend donc pas pourquoi on utilise cette manière plutôt que de faire :
new ma_class($param);
Quelqu'un peut-il m'expliquer la nuance qu'il y a entre les deux?
Merci de votre aide et éclaircissement.
C'est assez rare comme utilisation (tu me l'a fait découvrir :D)
Alors pour résumé tu as ta class (on va appeller A qui a cette méthode "forge")
Imaginons que tu as la classe B qui extend de A
Si tu fais A::forge() ça retourne A (jusque là rien de fou (un new suffirait)
Si tu fais un B::forge() ça retourne B
Jpense que l'avantage c'est de pouvoir déclarer une sorte de constructeur commun au sous objet.
Un petit bout de code pour mieux comprendre encore :
class Foo {
public static function getInstance() {
return new self();
}
}
class Bar extends Foo {}
var_dump(Bar::getInstance());
// => object(Foo)[1]
// VS
class Foo {
public static function getInstance() {
return new static();
}
}
class Bar extends Foo {}
var_dump(Bar::getInstance());
// => object(Bar)[1]
Donc avec static() tu fais référence à la classe qui appel : Bar ::getInstance()
Je pense ne pas me tromper si je complète avec :
Bien faire attention avec PHP5.2: self et static sont différent comme montré plus haut:
Après réflexion on peut compléter par: 2 raisons d'utiliser ce système pour créer un objet.
La première, qui se rencontre souvent mais n'est pas applicable dans le cas présent, est de faire un singleton.
La seconde est de contourner certaines limitations de php 5.3 (la version 5.4 de php corrigera ce problème). Un exemple de limitation et l'utilisation de cette construction "externe" pour contourner :
<?php
class Toto
{
public static function forge()
{
return new static();
}
public function foo()
{
return 42;
}
public function __toString()
{
return 'bar';
}
}
//$val = new Toto()->foo();
$val = Toto::forge()->foo();
//echo 'Test: ' . new Toto() . PHP_EOL;
echo 'Test: ' . Toto::forge() . PHP_EOL;
?>
En commentaire ce que l'on souhaitais faire et qui ne fonctionne pas dans les versions antérieurs à 5.4 de php. Juste en dessous la manière de contourner.
le static qui est apparut dans php5.3 est effectivement de plus en plus utilisé et pour cause. Déjà on peut le voir sur certaine class du coeur dans Symfony2 ou bien dans ZendFramework 2 aussi et déjà dans le 1 les class et méthode static utilisait le static:: plutôt que le self::.
Dans Fuelphp et Laravel les "Late statics Binding" sont abondamment utilisé (peut être un peu trop à mon goût mais bon).
Pourquoi ? :
Cel évite la duplication et doublons d'une instance de class. On ne va pas le faire sur toute nos class bien entendu mais certain ayant une vocation propre au noyau, une class autonome.
Ce qui est déroutant c'est effectivement les instances de new Static() cela rend dynamique l'appelle de la class plutôt que d'utiliser new className() mais c'est surtout afin de pouvoir bénéficier de l'instance courante de notre class à un instant T.