Un metodo o una proprietà static appartiene alla classe stessa invece che a un oggetto. Chiami un metodo statico con ClassName::method() e leggi una proprietà statica con ClassName::$property, senza creare prima un oggetto. Dentro la classe, self:: si riferisce agli stessi membri.
Non c'è nessun new Temperature(). I membri statici sono utili per le funzioni di supporto che non hanno bisogno dello stato di un oggetto (conversioni, factory, validazione) e per i dati che appartengono alla classe nel suo insieme, come un contatore.
Le proprietà statiche sono condivise da tutti gli oggetti
Una proprietà normale ha un valore per oggetto. Una proprietà statica ha un valore per l'intera classe, quindi ogni oggetto vede lo stesso. Qui ogni nuovo User incrementa un contatore condiviso e riceve l'ID successivo:
Nota il $ in self::$nextId: le proprietà statiche lo mantengono dopo ::, mentre le costanti (self::MAX) no. Una proprietà statica vive solo per una richiesta PHP. Su un sito web tipico (PHP-FPM o Apache) riparte da capo a ogni caricamento di pagina, quindi non è il posto dove salvare dati tra un visitatore e l'altro.
I metodi statici non hanno $this
Un metodo statico viene eseguito senza un oggetto, quindi $this al suo interno non esiste. Un metodo statico può chiamare altri metodi statici con self::, ma non può leggere le proprietà normali. Anche chiamare staticamente un metodo normale fallisce:
La direzione opposta va bene: un metodo normale può chiamare quelli statici, come fa withSeparator() con self::make().
self vs static: late static binding
self:: punta alla classe in cui il codice è scritto. static:: punta alla classe su cui il metodo è stato chiamato a runtime. La differenza emerge solo con l'ereditarietà, e conta soprattutto per i metodi factory:
Post::createWithSelf() restituisce un Model, che non è quasi mai ciò che voleva chi chiama. static si risolve in Post perché è la classe indicata nella chiamata; PHP lo chiama late static binding. Usa static:: e new static() nei metodi destinati a essere ereditati, e self:: quando intendi davvero questa esatta classe. La stessa regola vale per le costanti: static::TABLE prende il TABLE proprio di una figlia, mentre self::TABLE legge sempre quello della classe in cui è scritto il codice.
Le proprietà statiche ereditate sono condivise
Una classe figlia condivide la proprietà statica del padre a meno che non ne dichiari una propria. È la classica sorpresa di static: due sottoclassi che contano nello stesso numero.
Apples non ha un $count proprio, quindi Apples::$count è Counter::$count, ed entrambi stampano 2. Pears ridichiara la proprietà e conta per conto suo. Una proprietà statica dichiarata in un trait si comporta diversamente: ogni classe che usa il trait riceve una copia separata.
Variabili statiche dentro le funzioni
static ha un secondo significato dentro il corpo di una funzione: una variabile statica mantiene il suo valore tra una chiamata e l'altra. Il valore iniziale viene assegnato solo la prima volta che la funzione viene eseguita:
Il secondo slowSquare(12) salta il calcolo. Come le proprietà statiche, questi valori si azzerano alla fine di ogni richiesta. La pagina sulle variabili tratta lo scope delle variabili in generale.
Quando static è la scelta sbagliata
I metodi statici sono comodi, e questo li rende facili da abusare. Una classe i cui metodi leggono e scrivono tutti proprietà statiche è stato globale con il nome di una classe sopra: ogni chiamante lo condivide, i test non possono averne una copia nuova e non puoi sostituirla con un'implementazione diversa.
Buoni usi di static: funzioni di supporto pure senza stato (Slug::make()), costruttori con nome (Color::fromHex()) e costanti di classe. Se un metodo ha bisogno di dati che potrebbero cambiare tra due utilizzi, vuole un oggetto.
Domande frequenti
Come chiamo un metodo statico in PHP?
Con il nome della classe e ::: MathHelper::square(4). Dentro la stessa classe usa self::square(4) o static::square(4). Non serve alcun oggetto, e dentro un metodo statico non c'è $this.
Qual è la differenza tra self e static in PHP?
self:: indica sempre la classe in cui il codice è scritto. static:: indica la classe su cui il metodo è stato effettivamente chiamato, che può essere una classe figlia; si chiama late static binding. Quindi nel metodo create() di un padre, new self() costruisce sempre il padre, mentre new static() costruisce la figlia che l'ha chiamato.
Cos'è una proprietà statica in PHP?
Una proprietà dichiarata public static int $count = 0; appartiene alla classe, quindi c'è un solo valore condiviso da ogni oggetto di quella classe (e delle sue figlie, a meno che una figlia non la ridichiari). Leggila e scrivila con ClassName::$count o self::$count; nota il $.
Posso chiamare un metodo statico su un oggetto in PHP?
Sì. $obj->square(4) e $obj::square(4) chiamano entrambi il metodo statico della classe dell'oggetto, ma dentro non c'è comunque $this. È la direzione opposta a fallire, chiamare un metodo non statico come ClassName::method(): da PHP 8 lancia un Error.
Posso usare $this in un metodo statico?
No. Un metodo statico viene eseguito senza un oggetto, quindi lì $this non è definito e usarlo lancia un Error ("Using $this when not in object context"). Usa self:: o static:: per raggiungere gli altri membri statici.