Jaka jest różnica między użyciem self
a static
w poniższym przykładzie?
class Foo
{
protected static $bar = 1234;
public static function instance()
{
echo self::$bar;
echo "\n";
echo static::$bar;
}
}
Foo::instance();
produkuje
1234
1234
Odpowiedzi:
Kiedy używasz
self
odniesienia do członka klasy, odnosisz się do klasy, w której używasz słowa kluczowego. W takim przypadku TwojaFoo
klasa definiuje chronioną właściwość statyczną o nazwie$bar
. Kiedy używaszself
wFoo
klasie do odwoływania się do właściwości, odwołujesz się do tej samej klasy.Dlatego jeśli spróbujesz użyć
self::$bar
innego miejsca w swojejFoo
klasie, ale maszBar
klasę z inną wartością właściwości, użyje onaFoo::$bar
zamiastBar::$bar
, co może nie być tym, czego zamierzałeś:Kiedy wywołujesz metodę via
static
, wywołujesz funkcję zwaną późnymi wiązaniami statycznymi (wprowadzoną w PHP 5.3).W powyższym scenariuszu użycie
self
spowodujeFoo::$bar
(1234). Użyciestatic
da w wynikuBar::$bar
(4321), ponieważ wstatic
przypadku interpreter bierze pod uwagę ponowną deklarację wBar
klasie podczas działania.Zwykle używasz późnych powiązań statycznych dla metod lub nawet samej klasy, a nie właściwości, ponieważ często nie deklarujesz ponownie właściwości w podklasach; przykład użycia
static
słowa kluczowego do wywołania konstruktora z późnym wiązaniem można znaleźć w tym pokrewnym pytaniu: Nowa jaźń vs. nowa statycznaJednak nie wyklucza to również używania
static
z właściwościami.źródło
<?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
użycie w środkuclass Foo
to to samo, co powiedzenieFoo::$abc
. Nie wpłynie na to żadna ponowna deklaracja$abc
w podklasie. AFAIK, jedynym powodem użyciaself
jest skrót, aby uniknąć używania nazwy klasyFoo
, która może być dłuższa. [Oznacza to również, że możesz zmienić nazwę klasy bez zmiany tych wszystkich miejsc - ale to nie jest powód, dla którego IMHO.] (Wybór nazw PHP jest niefortunny i wydaje się być odwrotny; „statyczny” to ten, który może się zmienić - co jest przeciwieństwem potocznego znaczenia słowa „statyczny” w języku naturalnym).Jak wspomniano, jedną z głównych różnic jest to, że
static
pozwala na późne wiązanie statyczne. Jednym z najbardziej przydatnych scenariuszy, które znalazłem, było tworzenie klas podstawowych dla klas singleton:Użycie
return static::$name
w klasie Base zwróci to, co zostało statycznie dołączone, gdy zostało rozszerzone. Jeśli było użyćreturn self::$name
wtedyB::getName()
zwróciłby pusty ciąg jako to, co jest zadeklarowana w klasie bazowej.źródło
Z
self
wezwaniem:Możesz zobaczyć powyżej, mimo że nadpisaliśmy the
$var
z nasząBar
klasą, nadal zwraca123
, ponieważ jawnie poprosiliśmy PHP oself
zmienną, która z kolei prosi oFoo
zmienną s.Teraz, jeśli zamienimy wywołanie na
static
, zamiast tego otrzymamyBar
nadpisaną wartość:Z
static
wezwaniem:źródło