Quelle est la différence entre utiliser self
et static
dans l'exemple ci-dessous?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
produit
1234
1234
Réponses:
Lorsque vous utilisez
self
pour faire référence à un membre de classe, vous faites référence à la classe dans laquelle vous utilisez le mot-clé. Dans ce cas, votreFoo
classe définit une propriété statique protégée appelée$bar
. Lorsque vous utilisezself
dans laFoo
classe pour faire référence à la propriété, vous faites référence à la même classe.Par conséquent, si vous avez essayé d'utiliser
self::$bar
ailleurs dans votreFoo
classe mais que vous aviez uneBar
classe avec une valeur différente pour la propriété, elle utiliserait à laFoo::$bar
place deBar::$bar
, ce qui n'est peut-être pas ce que vous prévoyez:Lorsque vous appelez une méthode via
static
, vous invoquez une fonctionnalité appelée liaisons statiques tardives (introduite dans PHP 5.3).Dans le scénario ci-dessus, l'utilisation
self
entraîneraFoo::$bar
(1234). Et l'utilisationstatic
donneraBar::$bar
(4321) car avecstatic
, l'interpréteur prend en compte la redéclaration au sein de laBar
classe lors de l'exécution.Vous utilisez généralement des liaisons statiques tardives pour les méthodes ou même la classe elle-même, plutôt que des propriétés, car vous ne redéclarez pas souvent les propriétés dans les sous-classes; un exemple d'utilisation du
static
mot - clé pour appeler un constructeur à liaison tardive peut être trouvé dans cette question connexe: New self vs. new staticCependant, cela n'empêche pas non plus d'utiliser
static
avec des propriétés.la source
<?php class Foo { public static $bar = 1234; public static function a( ) { echo 'static'.static::$bar; echo 'self'.self::$bar; } } class Bar extends Foo { public static $bar = 4321; } (new Bar())->a(); ?>
self::$abc
lorsqu'il est utilisé à l'intérieur,class Foo
c'est la même chose que de direFoo::$abc
. Il ne sera affecté par aucune re-déclaration de$abc
dans une sous-classe. AFAIK, la seule raison à utiliserself
est en tant que raccourci, pour éviter d'utiliser le nom de la classeFoo
, qui peut être plus long. [Cela signifie également que vous pouvez changer le nom de la classe sans changer tous ces endroits - mais ce n'est pas vraiment une raison à mon humble avis.] (Le choix des noms par PHP est malheureux et semble à l'envers; "statique" est celui qui peut changer - ce qui est opposé à la signification familière du mot «statique» en langage naturel.)Comme mentionné, l'une des principales différences est qu'elle
static
permet des liaisons statiques tardives. L'un des scénarios les plus utiles que j'ai trouvés était pour la création de classes de base pour les classes Singleton:En utilisant
return static::$name
dans la classe Base renverra ce qui était attaché statiquement lors de son extension. Si vous deviez utiliserreturn self::$name
alorsB::getName()
renverrait une chaîne vide comme c'est ce qui est déclaré dans la classe de base.la source
Avec
self
appel:Vous pouvez voir ci-dessus, même si nous avons remplacé le
$var
avec notreBar
classe, il renvoie toujours123
, car nous avons explicitement demandé à PHP laself
variable, qui à son tour demande laFoo
variable s à la place.Maintenant, si nous échangeons l'appel avec
static
, nous obtiendrons à la place laBar
valeur remplacée:Avec
static
appel:la source