Costanti di classe in PHP OOP
Impara le costanti di classe PHP: dichiarale con const, controlla la visibilità, usa array ed espressioni come valori, e accedi tramite self, static o il nome della classe.
Una costante di classe è un valore fisso e nominato che appartiene a una classe piuttosto che a un singolo oggetto. Viene definita una volta sola, non può mai essere riassegnata durante l'esecuzione, ed è condivisa da ogni istanza della classe. Le costanti sono il modo per dare nomi significativi ai valori "magici" da cui dipende il codice — un'aliquota fiscale, una stringa di stato, una versione API — in modo che risiedano in un unico posto invece di essere sparse come letterali.
Questo capitolo spiega come dichiarare le costanti di classe con const, come leggerle con self, static e il nome della classe, come controllarne la visibilità e come si comportano con l'ereditarietà e le interfacce. Tutti gli esempi seguenti funzionano con PHP 8.
Perché usare le costanti di classe?
Ricorri a una costante di classe quando un valore è noto in anticipo e non deve mai cambiare durante l'esecuzione dello script:
- Fonte unica di verità. Definisci un valore come
Order::SHIPPING_FEEuna sola volta; ogni chiamante legge lo stesso numero. - Leggibilità.
Circle::PIdice molto di più di un semplice3.14159nascosto in un calcolo. - Sicurezza. PHP rifiuta qualsiasi tentativo di riassegnare una costante, quindi un errore di battitura non può sovrascriverla silenziosamente.
- Nessun oggetto necessario. Poiché una costante appartiene alla classe, puoi leggerla senza creare un'istanza.
Le costanti di classe si differenziano dalle variabili ordinarie in due modi importanti: vengono scritte senza il simbolo del dollaro (MAX_USERS, non $MAX_USERS), e sono immutabili una volta definite.
Definire una costante di classe
Dichiara una costante all'interno del corpo della classe con la parola chiave const, un nome (convenzionalmente in UPPER_SNAKE_CASE) e un valore:
<?php
class MyClass {
const CONSTANT = 'constant value';
public function showConstant() {
echo self::CONSTANT . "\n";
}
}Questo definisce CONSTANT su MyClass. Una costante di classe non è la stessa cosa di una costante globale creata con define(): const appartiene alla classe e si raggiunge tramite ::, mentre define() registra un nome nello scope globale.
Il valore può essere un'espressione costante — un calcolo che PHP può risolvere al momento della compilazione — e persino un array:
<?php
class Circle {
const PI = 3.14159;
const TWO_PI = self::PI * 2; // built from another constant
const UNITS = ['mm', 'cm', 'm'];
}
echo Circle::TWO_PI . "\n"; // 6.28318
echo Circle::UNITS[1] . "\n"; // cmQuello che non puoi usare è qualcosa che è noto solo a runtime — chiamate a funzioni, istanze di oggetti o $variabili non sono consentite nel valore di una costante.
Accedere a una costante di classe
Il modo in cui leggi una costante dipende da dove ti trovi:
- Dall'esterno della classe, usa il nome della classe:
MyClass::CONSTANT. - Dall'interno della classe, usa la parola chiave
self:self::CONSTANT.
constant value
constant valueLa prima riga legge la costante staticamente tramite il nome della classe — nessun oggetto necessario. La seconda passa attraverso un metodo di istanza che usa self::CONSTANT. Nota che si accede alle costanti con ::, mai con l'operatore oggetto -> che usi per le proprietà.
Controllare la visibilità
A partire da PHP 7.1, le costanti di classe accettano gli stessi modificatori di visibilità delle proprietà e dei metodi: public (il predefinito), protected e private. Questo ti permette di nascondere i dettagli di implementazione che appartengono alla classe ma non dovrebbero essere letti dall'esterno.
<?php
class Config {
public const VERSION = '2.0';
protected const API_KEY = 'secret-123';
private const SALT = 'x9f2';
public function describe(): string {
return self::VERSION . ' / ' . self::API_KEY . ' / ' . self::SALT;
}
}
echo Config::VERSION . "\n"; // 2.0 — public, readable anywhere
$c = new Config();
echo $c->describe() . "\n"; // 2.0 / secret-123 / x9f2Qui Config::VERSION è accessibile ovunque, mentre API_KEY e SALT possono essere raggiunti solo dall'interno della classe (o, per protected, dalle sue sottoclassi). Tentare di leggere Config::SALT dall'esterno genera un errore.
Costanti ed ereditarietà
Le sottoclassi ereditano le costanti del genitore e possono sovrascriverle. La parola chiave che usi per leggere la costante decide quale versione ottieni:
self::NAMEviene risolto quando il codice viene scritto — indica sempre la costante nella classe dove è definito il metodo.static::NAMEviene risolto a runtime rispetto alla classe effettiva che è stata chiamata. Questo si chiama late static binding.
<?php
interface HasStatus {
const ACTIVE = 'active'; // interface constants are always public
}
class Order implements HasStatus {
const SHIPPING_FEE = 5.00;
public function status(): string {
return self::ACTIVE;
}
}
class ExpressOrder extends Order {
const SHIPPING_FEE = 15.00;
public function fee(): float {
return static::SHIPPING_FEE; // uses the called class's value
}
}
echo Order::ACTIVE . "\n"; // active (inherited from the interface)
echo (new ExpressOrder())->fee() . "\n"; // 15
echo (new ExpressOrder())->status() . "\n"; // activeAnche le interfacce possono dichiarare costanti; sono implicitamente public e condivise da ogni classe che le implementa. Se hai bisogno di una costante che le sottoclassi non devono sovrascrivere, contrassegnala come final (PHP 8.1+): final const ID = 100;. PHP 8.3 ha aggiunto anche le costanti tipizzate, ad esempio const string LABEL = 'base';.
Per ulteriori informazioni sul comportamento delle sottoclassi, consulta Ereditarietà PHP, e per la funzionalità correlata dei dati a livello di classe, Proprietà statiche PHP.
Insidie comuni
- Nessun simbolo del dollaro.
const RATE = 0.2;— scrivere$RATEè un errore di sintassi. ::, non->. Le costanti si raggiungono sempre con l'operatore di risoluzione dello scope.- I valori a runtime vengono rifiutati. Il valore di una costante deve essere un'espressione costante;
const NOW = time();non verrà compilato. selfvsstatic. Usastatic::quando intendi che una sottoclasse possa sovrascrivere il valore; altrimentiself::è la scelta più sicura e prevedibile.
Conclusione
Le costanti di classe ti forniscono valori nominati, immutabili e con scope di classe, definiti con const e letti tramite ::. Usale per centralizzare valori fissi, migliorare la leggibilità e bloccare i dati che non dovrebbero mai cambiare a runtime. Combinale con i modificatori di visibilità per nascondere i dettagli interni, e ricorda la distinzione tra self e static una volta che entra in gioco l'ereditarietà.