Come le Property Hooks Trasformano il Tuo Codice in PHP 8.4
Nel precedente articolo, Novità PHP 8.4, ti ho parlato delle nuove funzionalità introdotte con la versione 8.4.1 di PHP, rilasciata il 21 novembre 2024. Ora voglio approfondire una di queste novità: le Property Hooks.
Questa caratteristica permette di gestire meglio le proprietà di una classe, rendendo il codice più semplice e veloce da scrivere. Inoltre, avvicina PHP a linguaggi come Python, grazie a una sintassi più moderna e intuitiva.
Prima di PHP 8.4: Come funzionavano Getter e Setter?
In PHP, quando avevi bisogno di controllare come una proprietà di una classe
veniva letta o modificata, usavi i metodi getter e setter. Questi metodi
servono per proteggere le proprietà dichiarate come private
(cioè non
direttamente accessibili dall'esterno della classe).
Ecco un esempio di come si faceva prima:
class Locale
{
private string $languageCode;
private string $countryCode;
public function __construct(string $languageCode, string $countryCode)
{
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}
public function getLanguageCode(): string
{
return $this->languageCode;
}
public function setLanguageCode(string $languageCode): void
{
$this->languageCode = $languageCode;
}
public function getCountryCode(): string
{
return $this->countryCode;
}
public function setCountryCode(string $countryCode): void
{
$this->countryCode = strtoupper($countryCode);
}
public function setCombinedCode(string $combinedCode): void
{
[$languageCode, $countryCode] = explode('_', $combinedCode, 2);
$this->setLanguageCode($languageCode);
$this->setCountryCode($countryCode);
}
public function getCombinedCode(): string
{
return \sprintf("%s_%s", $this->languageCode, $this->countryCode);
}
}
Come vedi, ci sono molti metodi, anche per fare cose semplici come leggere o modificare una proprietà. Questo crea alcuni problemi:
- Molto codice superfluo: Molti metodi sono quasi identici.
- Manutenzione più complicata: Se decidi di cambiare qualcosa, devi modificare più punti nel codice.
- Poca chiarezza: Per capire come funziona una proprietà, devi cercare il getter o il setter corrispondente.
- Accesso indiretto: Le proprietà non sono direttamente accessibili, costringendo gli sviluppatori a interfacciarsi sempre attraverso i metodi dedicati.
PHP 8.4: Cosa sono le Property Hooks?
Con le Property Hooks, puoi definire direttamente come una proprietà deve comportarsi quando viene letta (get) o modificata (set). Non serve più scrivere tanti metodi separati, tutto è incluso nella definizione della proprietà stessa.
Ecco lo stesso esempio riscritto usando le Property Hooks:
class Locale
{
public string $languageCode;
public string $countryCode
{
set (string $value) {
$this->countryCode = strtoupper($value);
}
}
public string $combinedCode
{
get => \sprintf("%s_%s", $this->languageCode, $this->countryCode);
set (string $value) {
[$this->languageCode, $this->countryCode] = explode('_', $value, 2);
}
}
}
Questo nuovo approccio offre diversi vantaggi:
Sintassi Concisa: Getter e setter vengono definiti direttamente all'interno della dichiarazione delle proprietà, eliminando la necessità di metodi separati.
Maggiore leggibilità: Il codice risulta più chiaro e lineare, consentendo di vedere subito le regole di accesso e modifica delle proprietà.
Performance migliorate: L'accesso diretto alle proprietà, anziché passare per metodi dedicati, rende il codice più performante in situazioni di uso intensivo.
Accessibilità diretta: Le proprietà possono essere lette e scritte con una sintassi semplice e naturale:
$brazilianPortuguese->countryCode; // Accesso diretto alla proprietà
Il hook get
Il hook get
controlla cosa succede quando leggi una proprietà. Ad esempio:
class Persona
{
public string $nomeCompleto {
get {
return $this->nome . ' ' . $this->cognome;
}
}
public function __construct(
public string $nome,
public string $cognome
) {}
}
$persona = new Persona('Mario', 'Rossi');
echo $persona->nomeCompleto; // Mario Rossi
In questo caso ogni volta che accediamo il metodo nomeCompleto
della classe
Persona
avremo la concatenazione del nome
e del cognome
divisi da spazio.
Compatibilità del Tipo
Il tipo del valore restituito dal hook get
deve corrispondere al tipo
dichiarato per la proprietà. Se i tipi non corrispondono, PHP tenterà di
convertire automaticamente il valore, a meno che i tipi stretti (strict types
) siano abilitati. Se i tipi stretti sono abilitati, è necessario
assicurarsi che il valore restituito corrisponda esattamente al tipo della
proprietà, altrimenti verrà generato un errore.
Il hook set
Il hook set
controlla cosa accade quando modifichi una proprietà. Ecco un
esempio:
class Persona
{
public string $nome {
set(string $value) {
$this->nome = strtoupper($value);
}
}
public function __construct(string $nome)
{
$this->nome = $nome;
}
}
$persona = new Persona('mario');
echo $persona->nome; // MARIO
Nell'esempio, il set
garantisce che qualsiasi nome assegnato a una classe
Persona
venga memorizzato in lettere maiuscole
Compatibilità del Tipo
Similmente al hook get
, il tipo del valore passato al hook set
deve essere
compatibile con il tipo della proprietà. Se i tipi non corrispondono, PHP
genererà un errore se i tipi stretti (strict types
) sono abilitati.
Proprietà di classe write-only
e read-only
Con i property hook, puoi creare proprietà che sono solo scrivibili o solo leggibili.
write-only
(Sola scrittura): Puoi assegnare un valore ma non leggerlo. Questo avviene quando definisci un hookset
ma non un hookget
.read-only
(Sola lettura): Puoi leggere il valore ma non assegnarlo. Questo avviene quando definisci un hookget
ma non un hookset
.
Esempi di proprietà in Sola Scrittura (write-only
)
Ecco un esempio in cui puoi impostare una password ma non leggerla:
class Utente
{
public string $password {
set(string $valore) {
$this->hashedPassword = password_hash($valore, PASSWORD_DEFAULT);
}
}
private string $hashedPassword;
}
$utente = new Utente();
$utente->password = 'segreto';
// echo $utente->password; // Errore: impossibile accedere a una proprietà sola scrittura
Esempi di proprietà in Sola Lettura (read-only
)
Ecco un esempio in cui puoi leggere un valore calcolato ma non impostarlo direttamente:
class Cerchio
{
public float $raggio;
public float $area {
get {
return pi() * $this->raggio ** 2;
}
}
public function __construct(float $raggio)
{
$this->raggio = $raggio;
}
}
$cerchio = new Cerchio(5);
echo $cerchio->area; // 78.5398...
// $cerchio->area = 100; // Errore: impossibile impostare una proprietà sola lettura
Cose da Tenere a Mente Quando Si Usano i Property Hook
Quando lavori con i property hook in PHP, ci sono alcuni punti importanti da considerare:
Solo per le Proprietà degli Oggetti: I property hook possono essere applicati solo alle proprietà degli oggetti, non a quelle statiche. Se una proprietà è statica, non può avere un hook.
Comportamento Sovrascritto: I property hook sovrascrivono qualsiasi comportamento predefinito per la lettura o scrittura di una proprietà. La logica personalizzata nei hook controllerà come la proprietà viene accessibile o modificata.
Accesso a Metodi e Proprietà: I property hook possono accedere a tutti i metodi e proprietà dell’oggetto, siano essi pubblici, privati o protetti. Questo include anche le proprietà che potrebbero avere i loro hook.
No ai Riferimenti: Non puoi impostare riferimenti su proprietà con hook. Questo perché modificare un valore tramite riferimento bypasserebbe l’hook
set
definito per la proprietà.Ereditarietà e Ridefinizione degli Hook: In una classe figlia, puoi ridefinire singoli hook per una proprietà ridefinendo solo gli hook che desideri cambiare. Il tipo e la visibilità della proprietà seguono le loro regole, e ogni hook può sovrascrivere indipendentemente l’implementazione della classe genitore.
Conclusioni
Le Property Hooks rendono il codice più semplice, leggibile e sicuro. Ora puoi controllare ogni aspetto delle tue proprietà direttamente nella classe. Inizia a usarle e scoprirai quanto è più facile lavorare con PHP!