Was ist der Unterschied zwischen self
und static
im folgenden Beispiel?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
produziert
1234
1234
Antworten:
Wenn Sie
self
auf ein Klassenmitglied verweisen, beziehen Sie sich auf die Klasse, in der Sie das Schlüsselwort verwenden. In diesem FallFoo
definiert Ihre Klasse eine geschützte statische Eigenschaft namens$bar
. Wenn Sieself
in derFoo
Klasse auf die Eigenschaft verweisen, verweisen Sie auf dieselbe Klasse.Wenn Sie also versuchen, eine andere Klasse
self::$bar
in IhrerFoo
Klasse zu verwenden, aber eineBar
Klasse mit einem anderen Wert für die Eigenschaft haben, wird dieseFoo::$bar
anstelle von verwendetBar::$bar
, was möglicherweise nicht das ist, was Sie beabsichtigen:Wenn Sie eine Methode über aufrufen , rufen
static
Sie eine Funktion auf, die als späte statische Bindungen bezeichnet wird (eingeführt in PHP 5.3).Im obigen Szenario führt die Verwendung
self
zuFoo::$bar
(1234). Und usingstatic
führt zuBar::$bar
(4321), da mitstatic
mit der Interpreter die Neudeklaration innerhalb derBar
Klasse zur Laufzeit berücksichtigt wird .Normalerweise verwenden Sie späte statische Bindungen für Methoden oder sogar die Klasse selbst anstelle von Eigenschaften, da Sie Eigenschaften in Unterklassen nicht häufig neu deklarieren. Ein Beispiel für die Verwendung des
static
Schlüsselworts zum Aufrufen eines spät gebundenen Konstruktors finden Sie in dieser verwandten Frage: New self vs. new staticDies schließt jedoch auch die Verwendung
static
mit Eigenschaften nicht aus .quelle
<?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
Wenn es im Inneren verwendet wird,class Foo
ist es dasselbe wie zu sagenFoo::$abc
. Es wird von keiner erneuten Deklaration$abc
in einer Unterklasse betroffen sein . AFAIK, der einzige Grund für die Verwendungself
ist die Abkürzung, um die Verwendung des Klassennamens zu vermeidenFoo
, der möglicherweise länger ist. [Es bedeutet auch, dass Sie den Klassennamen ändern können, ohne all diese Stellen zu ändern - aber das ist meiner Meinung nach kein großer Grund.] (Die Wahl der Namen von PHP ist unglücklich und scheint rückwärts zu sein; "statisch" kann sich ändern - was ist entgegengesetzt zur umgangssprachlichen Bedeutung des natürlichen Wortes "statisch".)Wie bereits erwähnt, besteht einer der Hauptunterschiede darin,
static
dass späte statische Bindungen möglich sind. Eines der nützlichsten Szenarien, das ich gefunden habe, war das Erstellen von Basisklassen für Singleton-Klassen:Bei Verwendung
return static::$name
in der Basisklasse wird zurückgegeben, was statisch angehängt war, als es erweitert wurde. Wenn Sie sind verwenden ,return self::$name
dannB::getName()
würde eine leere Zeichenfolge zurück , wie das ist , was in der Basisklasse deklariert wird.quelle
Mit
self
Anruf:Sie können oben sehen, obwohl wir das
$var
mit unsererBar
Klasse überschrieben haben , wird es dennoch zurückgegeben123
, da wir PHP explizit nach derself
Variablen gefragt haben , die wiederum nach der VariablenFoo
s fragt .Wenn wir nun den Anruf mit tauschen
static
, erhalten wir stattdessen denBar
überschriebenen Wert:Mit
static
Anruf:quelle