PHP OOP: Comprendere i Metodi Statici
Impara i metodi statici PHP: definirli, chiamarli, self:: vs static::, contatori, factory method e casi particolari — con esempi pratici.
Un metodo statico è un metodo dichiarato con la parola chiave static che appartiene alla classe stessa anziché a un singolo oggetto creato da essa. Poiché è legato alla classe, puoi chiamarlo direttamente con il nome della classe e l'operatore di risoluzione dell'ambito (::) — senza usare new.
Questo capitolo mostra come definire e chiamare i metodi statici, come differiscono dai metodi normali (di istanza), come si comportano self:: e static:: al loro interno, e i pattern in cui i metodi statici sono davvero utili (utility, contatori e factory method). Se sei nuovo alle classi, leggi prima Classi e Oggetti PHP.
Cosa sono i metodi statici in PHP?
I metodi normali operano su un oggetto specifico e possono leggere i dati dell'istanza tramite $this. Un metodo statico non ha $this — non è legato ad alcuna istanza, quindi può lavorare solo con gli argomenti passati e con i membri statici della classe.
Questo rende i metodi statici ideali per operazioni senza stato: un calcolo che dipende solo dai suoi input, non dallo stato di un particolare oggetto. Calcolare la media di un elenco di numeri è un esempio classico.
class Math
{
public static function average(array $numbers): float
{
return array_sum($numbers) / count($numbers);
}
}Perché usare i metodi statici?
| Motivo | Cosa significa in pratica |
|---|---|
| Assenza di stato | L'output dipende solo dagli argomenti, quindi il risultato è prevedibile e facile da testare. |
| Nessuna istanziazione | Si evita new ClassName() — comodo per funzioni helper/utility. |
| Stato condiviso | I metodi statici possono leggere e aggiornare le proprietà statiche, consentendo a una classe di tracciare dati tra tutti i suoi oggetti (es. un contatore). |
| Factory method | Un metodo statico può costruire e restituire un'istanza configurata, offrendo un'alternativa più chiara a un costruttore complesso. |
Il compromesso: poiché i metodi statici non possono essere sovrascritti tramite un riferimento a oggetto normale e non mantengono lo stato dell'istanza, abusarne rende il codice più difficile da simulare e testare. Preferisci i metodi di istanza quando il comportamento dipende dallo stato dell'oggetto.
Come definire e chiamare un metodo statico
Aggiungi static prima del nome del metodo, poi chiamalo con ClassName::method():
<?php
class Math
{
public static function average(array $numbers): float
{
return array_sum($numbers) / count($numbers);
}
}
$average = Math::average([1, 2, 3, 4, 5]);
echo $average; // 3Il token :: è l'operatore di risoluzione dell'ambito — lo stesso operatore usato per le costanti di classe.
self:: vs static:: e l'assenza di $this
All'interno di un metodo statico non puoi usare $this, perché non c'è alcuna istanza a cui fare riferimento. Per raggiungere un altro membro statico della classe si usa self:: o static::.
self::si risolve nella classe in cui il metodo è scritto.static::usa il late static binding — si risolve nella classe effettivamente chiamata a runtime, il che conta con l'ereditarietà.
<?php
class Base
{
public static function create(): string
{
return self::class; // always "Base"
}
public static function make(): string
{
return static::class; // the called class
}
}
class Child extends Base {}
echo Base::create(), "\n"; // Base
echo Child::create(), "\n"; // Base (self:: is fixed to where it's written)
echo Child::make(), "\n"; // Child (static:: follows the call)Usa static:: quando una classe padre definisce un comportamento che le sottoclassi devono poter reindirizzare a sé stesse — la base del pattern factory descritto di seguito. Approfondisci in Ereditarietà PHP.
Metodi statici con proprietà statiche: un contatore
I metodi statici sono spesso abbinati alle proprietà statiche per mantenere uno stato condiviso tra tutti gli oggetti di una classe.
<?php
class User
{
public static int $count = 0;
public function __construct(public string $name)
{
self::$count++;
}
public static function total(): int
{
return self::$count;
}
}
new User('Ada');
new User('Linus');
echo User::total(); // 2Nota come total() legge self::$count senza un oggetto — la proprietà appartiene alla classe, non a un singolo User.
Factory method
Un metodo statico che restituisce una nuova istanza è chiamato factory method. Fornisce un modo nominato e leggibile per costruire oggetti:
<?php
class Temperature
{
private function __construct(private float $celsius) {}
public static function fromCelsius(float $c): static
{
return new static($c);
}
public static function fromFahrenheit(float $f): static
{
return new static(($f - 32) * 5 / 9);
}
public function celsius(): float
{
return $this->celsius;
}
}
$t = Temperature::fromFahrenheit(212);
echo $t->celsius(); // 100Usando new static() (late static binding), una sottoclasse che chiama fromCelsius() ottiene un'istanza di sé stessa, non di Temperature.
Errori comuni
$thisnon è disponibile. Usarlo all'interno di un metodo statico genera un errore fatale — non esiste un oggetto corrente.- Metodi statici e di istanza possono condividere un nome solo tra classi, non nella stessa classe. All'interno di una classe ogni nome di metodo è unico.
- Si può chiamare un metodo statico su un oggetto (
$obj::method()o anche$obj->method()), ma viene eseguito comunque senza$this. Chiamarlo con$obj->è consentito ma fuorviante — preferisciClassName::method()per chiarezza. - Lo stato statico è globale per il processo. Un contatore statico è condiviso da ogni istanza e persiste per l'intera richiesta, il che può sorprendere nel codice a lunga esecuzione o nei test.
Conclusione
I metodi statici appartengono alla classe, vengono eseguiti senza un'istanza e non hanno accesso a $this. Eccellono per utility senza stato, stato a livello di classe tramite proprietà statiche e factory method che costruiscono oggetti configurati. Usa self:: quando intendi la classe che definisce il metodo e static:: quando le sottoclassi devono poter reindirizzare la chiamata a sé stesse. Ricorri ai metodi statici quando il comportamento è legato alla classe piuttosto che a un particolare oggetto — e preferisci i metodi di istanza quando non lo è.
Approfondisci con Proprietà Statiche PHP e Costanti di Classe PHP.