Menu

static w PHP: metody i właściwości statyczne, self vs static

Metoda lub właściwość static należy do klasy, a nie do obiektu: metodę wywołujesz przez ClassName::method(), a właściwość czytasz przez ClassName::$count, bez new. Poznaj self:: vs static:: (późne wiązanie statyczne), new static, zmienne statyczne w funkcjach i sytuacje, w których static to złe narzędzie.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Metoda lub właściwość static należy do samej klasy, a nie do żadnego obiektu. Metodę statyczną wywołujesz przez ClassName::method(), a właściwość statyczną czytasz przez ClassName::$property, bez wcześniejszego tworzenia obiektu. Wewnątrz klasy do tych samych elementów odwołuje się self::.

Nigdzie nie ma new Temperature(). Elementy statyczne przydają się w funkcjach pomocniczych, które nie potrzebują stanu obiektu (konwersje, fabryki, walidacja), i dla danych należących do klasy jako całości, takich jak licznik.

Właściwości statyczne są współdzielone przez wszystkie obiekty

Zwykła właściwość ma jedną wartość na obiekt. Właściwość statyczna ma jedną wartość dla całej klasy, więc każdy obiekt widzi tę samą. Tutaj każdy nowy User zwiększa wspólny licznik i dostaje kolejny identyfikator:

Zwróć uwagę na $ w self::$nextId: właściwości statyczne zachowują go po ::, a stałe (self::MAX) nie. Właściwość statyczna żyje tylko przez jedno żądanie PHP. Na typowej stronie WWW (PHP-FPM lub Apache) zaczyna od nowa przy każdym wczytaniu strony, więc nie jest miejscem na przechowywanie danych między odwiedzającymi.

Metody statyczne nie mają $this

Metoda statyczna działa bez obiektu, więc nie istnieje w niej $this. Metoda statyczna może wywoływać inne metody statyczne przez self::, ale nie może czytać zwykłych właściwości. Statyczne wywołanie zwykłej metody też się nie udaje:

Kierunek odwrotny jest w porządku: zwykła metoda może wywoływać metody statyczne, tak jak withSeparator() robi z self::make().

self vs static: późne wiązanie statyczne

self:: wskazuje klasę, w której napisano kod. static:: wskazuje klasę, na której wywołano metodę w czasie działania. Różnica wychodzi tylko przy dziedziczeniu, a najbardziej liczy się w metodach fabrycznych:

Post::createWithSelf() zwraca Model, czego wywołujący prawie nigdy nie chciał. static wskazuje na Post, bo to klasa wymieniona w wywołaniu; PHP nazywa to późnym wiązaniem statycznym (late static binding). Używaj static:: i new static() w metodach przeznaczonych do dziedziczenia, a self::, gdy naprawdę chodzi ci o tę konkretną klasę. Ta sama zasada dotyczy stałych: static::TABLE bierze własne TABLE potomka, a self::TABLE zawsze czyta to z klasy, w której napisano kod.

Odziedziczone właściwości statyczne są współdzielone

Klasa potomna współdzieli właściwość statyczną rodzica, chyba że zadeklaruje własną. To klasyczna niespodzianka ze static: dwie podklasy liczące do jednej liczby.

Apples nie ma własnego $count, więc Apples::$count to Counter::$count i oba wypisują 2. Pears deklaruje właściwość ponownie i liczy osobno. Właściwość statyczna zadeklarowana w traicie zachowuje się inaczej: każda klasa używająca traitu dostaje osobną kopię.

Zmienne statyczne w funkcjach

static ma drugie znaczenie wewnątrz treści funkcji: zmienna statyczna zachowuje wartość między wywołaniami. Wartość początkowa jest przypisywana tylko przy pierwszym wykonaniu funkcji:

Drugie slowSquare(12) pomija obliczenie. Podobnie jak właściwości statyczne, te wartości resetują się na koniec każdego żądania. Zasięg zmiennych ogólnie opisuje strona o zmiennych.

Kiedy static to zły wybór

Metody statyczne są wygodne i dlatego łatwo ich nadużywać. Klasa, której wszystkie metody czytają i zapisują właściwości statyczne, to stan globalny z nazwą klasy: współdzieli go każdy wywołujący, testy nie dostaną świeżej kopii, a podmiana implementacji jest niemożliwa.

Dobre zastosowania static: czyste funkcje pomocnicze bez stanu (Slug::make()), nazwane konstruktory (Color::fromHex()) i stałe dla całej klasy. Jeśli metoda potrzebuje danych, które mogą się różnić między dwoma użyciami, potrzebuje obiektu.

Najczęściej zadawane pytania

Jak wywołać metodę statyczną w PHP?

Nazwą klasy i ::: MathHelper::square(4). Wewnątrz tej samej klasy użyj self::square(4) albo static::square(4). Obiekt nie jest potrzebny, a w metodzie statycznej nie ma $this.

Czym różni się self od static w PHP?

self:: zawsze oznacza klasę, w której napisano kod. static:: oznacza klasę, na której faktycznie wywołano metodę, a może to być klasa potomna; nazywa się to późnym wiązaniem statycznym. W metodzie create() rodzica new self() zawsze buduje rodzica, a new static() buduje tego potomka, który ją wywołał.

Czym jest właściwość statyczna w PHP?

Właściwość zadeklarowana jako public static int $count = 0; należy do klasy, więc istnieje jedna wartość współdzielona przez wszystkie obiekty tej klasy (i jej potomków, chyba że potomek zadeklaruje ją ponownie). Czytaj i zapisuj ją przez ClassName::$count albo self::$count; zwróć uwagę na $.

Czy można wywołać metodę statyczną na obiekcie w PHP?

Tak. $obj->square(4) i $obj::square(4) wywołują metodę statyczną klasy obiektu, ale w środku nadal nie ma $this. Nie działa kierunek odwrotny: wywołanie metody niestatycznej jako ClassName::method() od PHP 8 rzuca Error.

Czy w metodzie statycznej można użyć $this?

Nie. Metoda statyczna działa bez obiektu, więc $this nie jest w niej zdefiniowane, a jego użycie rzuca Error ("Using $this when not in object context"). Aby sięgnąć do innych elementów statycznych, użyj self:: albo static::.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ