static
In PHP, la parola chiave "static" definisce proprietà e metodi a livello di classe accessibili senza istanziare un oggetto, condivisi tra tutte le istanze.
La parola chiave static in PHP
La parola chiave static in PHP ha due usi distinti, ed è utile tenerli separati fin dall'inizio:
- Membri di classe —
staticcontrassegna una proprietà o un metodo come appartenente alla classe stessa anziché a un singolo oggetto. Si accede a essi senza creare un'istanza e tutte le istanze condividono lo stesso valore. - Variabili locali statiche — all'interno di una funzione,
staticfa sì che una variabile locale mantenga il proprio valore tra le chiamate invece di essere reimpostata ogni volta.
Questo capitolo tratta entrambi gli usi, oltre alle parole chiave correlate self, static:: e parent:: che si incontrano quasi sempre insieme ai membri statici. Se classi e oggetti sono nuovi per te, leggi prima Classi e Oggetti.
Membri di classe statici
Una proprietà normale vive su ciascun oggetto. Una proprietà statica vive sulla classe — esiste esattamente una copia, condivisa da ogni istanza e accessibile anche quando non esiste alcuna istanza.
Sintassi di base
<?php
class MyClass {
public static $myProperty = "Hello, world!";
public static function myMethod() {
return self::$myProperty;
}
}Si accede a un membro statico con l'operatore di risoluzione dello scope ::, non con l'operatore oggetto ->:
<?php
echo MyClass::$myProperty; // Hello, world!
echo MyClass::myMethod(); // Hello, world!All'interno della classe, fai riferimento ai tuoi membri statici con self:: (o static::, spiegato di seguito) — mai con $this, poiché un metodo statico può essere eseguito senza alcun oggetto.
Per una copertura più approfondita, consulta Proprietà Statiche e Metodi Statici.
Variabili locali statiche
La stessa parola chiave fa qualcosa di completamente diverso all'interno di una funzione: fa sì che una variabile persista tra le chiamate. Senza static, una variabile locale viene reinizializzata a ogni chiamata; con essa, il valore iniziale viene impostato una sola volta e la variabile conserva il valore che aveva nell'ultima chiamata.
<?php
function counter() {
static $count = 0; // initialised only on the first call
$count++;
return $count;
}
echo counter(); // 1
echo counter(); // 2
echo counter(); // 3Questo è utile per memorizzare nella cache un risultato costoso o contare quante volte è stata eseguita una funzione, senza esporre una variabile globale.
Esempi
Vediamo alcuni esempi pratici di membri di classe statici:
Esempi della parola chiave static in PHP
<?php
// Example 1
class Counter
{
public static $count = 0;
public static function increment()
{
self::$count++;
}
}
Counter::increment();
Counter::increment();
echo Counter::$count . PHP_EOL;
// Example 2
class User
{
public static $name;
public static function setName($name)
{
self::$name = $name;
}
}
User::setName("John Doe");
echo User::$name;In Counter, la proprietà statica $count è condivisa, quindi due chiamate a increment() si accumulano fino a 2. In User, setName() memorizza i dati sulla classe stessa anziché su un oggetto.
self vs static (late static binding)
Quando si fa riferimento a un membro statico dall'interno di un metodo, si hanno due opzioni, e la differenza è importante nell'ereditarietà:
self::viene risolto al momento della compilazione — punta sempre alla classe in cui il codice è scritto.static::usa il late static binding — viene risolto al runtime alla classe che è stata effettivamente chiamata.
<?php
class Base {
public static function create() {
return new static(); // runtime class
}
public static function createSelf() {
return new self(); // always Base
}
}
class Child extends Base {}
echo get_class(Child::create()); // Child
echo "\n";
echo get_class(Child::createSelf()); // BaseUsa static:: quando una sottoclasse deve poter sovrascrivere il comportamento o essere quella istanziata — il pattern sopra è la base dei factory method. Usa self:: quando intendi specificamente questa classe. Per chiamare il metodo statico di un genitore, usa parent::. Consulta Ereditarietà per il quadro generale.
Casi d'uso comuni
- Contatori e stato condiviso — un singolo valore tracciato su tutte le istanze, come il
Countersopra. - Metodi di utilità / helper — funzioni stateless raggruppate sotto una classe, es.
Math::clamp(), chiamate senza un oggetto. - Factory method —
User::fromArray($data)restituisce un'istanza configurata;new static()la mantiene compatibile con le sottoclassi. - Singleton e cache semplici — una proprietà statica contiene la singola istanza o un risultato memoizzato.
Per valori condivisi nominati e immutabili, preferisci una costante di classe rispetto a una proprietà statica.
Insidie
- Nessun
$thisnei metodi statici. Un metodo statico può essere chiamato senza un oggetto, quindi$thisè indefinito. Accedere allo stato dell'istanza da un metodo statico è un segnale di cattiva progettazione. - Le proprietà statiche sono uno stato condiviso globale. Poiché ogni istanza condivide l'unica copia, modificarla da qualsiasi punto influenza tutti — è facile introdurre dipendenze nascoste e rompere l'isolamento dei test. Usale con consapevolezza.
::per lo statico,->per l'istanza.MyClass::$prop(statico) vs$obj->prop(istanza). Nota che$rimane nel nome della proprietà nella forma statica:Counter::$count, nonCounter::count.- Le variabili locali statiche sono per funzione, non per chiamata. Due chiamate ricorsive condividono la stessa variabile
static, il che può essere a volte sorprendente.
Conclusione
La parola chiave static svolge due compiti: definisce proprietà e metodi a livello di classe condivisi tra tutte le istanze e raggiungibili senza un oggetto, e fa sì che la variabile locale di una funzione sopravviva tra le chiamate. Combinala con self::, static:: e parent:: per controllare esattamente a quale classe si risolvono le tue chiamate statiche. Usa i membri statici per uno stato genuinamente condiviso e per helper stateless — ma tratta i dati statici mutabili condivisi con la stessa cautela che useresti con una variabile globale.