Come utilizzare le proprietà di sola lettura in PHP 8.1

0
137

PHP 8.1 aggiunge il supporto per un modificatore di sola lettura sulle proprietà della classe. Una proprietà contrassegnata in questo modo può essere impostata solo una volta. Il tentativo di modificare il valore di una proprietà di sola lettura dopo l'inizializzazione genererà un errore.

“Sola lettura” è un termine piuttosto vago, con implicazioni variabili nei singoli linguaggi di programmazione. In questo contesto, “sola lettura” significa davvero “immutabile”—puoi impostare il valore di una proprietà, ma non può essere modificato in seguito.

Proprietà di sola lettura in scrittura

Aggiungi il modificatore di sola lettura per rendere una proprietà di sola lettura. Dovrebbe essere posizionato tra il modificatore di accesso della proprietà e il suo typehint.

class Demo {   stringa pubblica $Mutabile;   stringa di sola lettura pubblica $Immutabile;   funzione pubblica __construct( stringa $Mutabile, stringa $Immutabile) {   $questo -> Mutabile = $Mutabile; $questo -> Immutabile = $Immutabile; }   }

$Mutable è una normale proprietà pubblica. Puoi cambiarne il valore in qualsiasi momento, sia all'interno dei metodi della classe che dall'esterno:

$demo = nuova demo("A", "X"); $dimostrazione -> Mutevole = "B";

$Immutable è leggermente diverso. Puoi ancora leggere il suo valore ogni volta che vuoi, ma qualsiasi modifica fallirà con un errore:

//genera un errore $demo -> Immutabile = "Y"; Annuncio

Il modificatore readonly è supportato anche nelle proprietà del costruttore promosso:

class Demo { funzione pubblica __construct( stringa di sola lettura pubblica $Immutable="foobar" ) {} }

Puoi comunque impostare la proprietà manualmente nel costruttore quando utilizzi la promozione con un valore predefinito. È il parametro della funzione che riceve il valore predefinito, non l'istanza della proprietà. La promozione ha lo stesso codice mostrato nell'esempio precedente.

Avvertenze

Le proprietà di sola lettura sono un semplice miglioramento della sintassi che puoi adottare a tuo piacimento. Non ci sono implicazioni di compatibilità con le versioni precedenti e il loro utilizzo è del tutto facoltativo. Se inizi ad aggiungerli, ci sono alcuni avvertimenti e limitazioni di cui essere a conoscenza.

A differenza delle proprietà normali, le proprietà di sola lettura non possono avere un valore predefinito nella loro definizione:

demo di classe { stringa di sola lettura protetta $pippo = "bar"; }

Questa istruzione definisce e inizializza $pippo. Non è possibile modificare il suo valore dopo l'inizializzazione, quindi la proprietà è effettivamente una costante. Di conseguenza, i valori predefiniti sono vietati e dovresti invece usare una costante reale:

classe Demo { const foo = "bar"; }

A seguito di questa restrizione, la sola lettura è supportata solo sulle proprietà digitate. La seguente proprietà ha una definizione illegale:

class Demo { protetto in sola lettura $pippo; } Pubblicità

Una proprietà non tipizzata, come $foo sopra, ha un valore predefinito implicito di null. Se era consentita la sola lettura, “nessuna costante implicita” la regola riemergerebbe. Le proprietà tipizzate distinguono tra “non inizializzato” e “null” stati, quindi esistono senza alcun valore finché non ne imposti uno esplicitamente.

Il modificatore di sola lettura ha regole speciali se usato come parte dell'ereditarietà della classe. Le classi figlio non possono aggiungere o rimuovere la sola lettura su proprietà definite dai genitori.

Rendere di sola lettura una proprietà scrivibile interromperebbe la classe genitore se i suoi metodi modificassero il valore. Sebbene la rimozione del vincolo sia apparentemente innocua, la RFC considera la sola lettura come una “restrizione intenzionale” di capacità che andrebbero perse se fossero consentiti gli override dell'ereditarietà. È vietato in modo che le classi padre possano affermare che i figli non possono causare effetti collaterali modificando proprietà che dovrebbero essere di sola lettura.

Le proprietà di sola lettura possono essere impostate solo all'interno dell'ambito in cui sono definiti. Ciò significa che le proprietà pubbliche non possono essere impostate dall'esterno di una classe, anche se non sono state inizializzate in precedenza:

classe Demo { stringa di sola lettura pubblica $pippo; }   $d = nuova demo(); $d -> pippo = "bar"; //illegale

L'inizializzazione deve avvenire all'interno della classe che definisce la proprietà. Di conseguenza, le proprietà di sola lettura sono più vicine ai campi immutabili di altri linguaggi di programmazione rispetto alle proprietà PHP preesistenti.

Il modificatore readonly si applica ugualmente a tutte le scritture. Non distingue tra accesso interno ed esterno. Non puoi avere una proprietà che è di sola lettura pubblica ma scrivibile all'interno della classe, anche se una futura estensione delle specifiche potrebbe consentirlo.

Pubblicità

Un ultimo trucco riguarda la parola chiave clone. Questo codice non funziona:

class Demo { funzione pubblica __construct( stringa pubblica $pippo ) {} }   $d = nuova demo("bar"); $d2 = clone $d; $d2 -> pippo = "pippo";

La clonazione segue le stesse regole dei normali accessi alle proprietà. Anche se il passaggio a foobar è la prima volta che si accede a foo su $ d2, la proprietà è già stata inizializzata dal processo di clonazione. C'è un'inizializzazione implicita durante il clone.

Quando usare le proprietà di sola lettura?

Le proprietà di sola lettura accelereranno notevolmente la creazione di classi semplici, che rappresentano strutture di dati. È comune scrivere classi usa e getta per contenere parametri di richiesta HTTP, oggetti di trasferimento dati e dati di risposta. Questi sono in genere immutabili, dove non ci si aspetta che le proprietà cambino dopo che la classe è stata costruita.

In precedenza avevi due scelte sgradevoli quando scrivevi classi di tipo struct: usare le proprietà pubbliche, velocizzando lo sviluppo ma permettendo modifica o dedica del tempo ad aggiungere manualmente metodi getter per esporre le proprietà protette.

//Non ideale: le proprietà possono essere modificate esternamente class UserCreationRequest { funzione pubblica __construct( stringa pubblica $Nome utente, stringa pubblica $Password ) {} }   //Neanche l'ideale – Molte classi di codice standard UserCreationRequest { funzione pubblica __construct( stringa protetta $Nome utente, stringa protetta $Password ) {}   funzione pubblica getUsername() : stringa { restituisce $this -> Nome utente; }   funzione pubblica getPassword() : stringa { restituisce $this -> Parola d'ordine; } }

Le proprietà di sola lettura rendono finalmente possibile l'approccio ideale:

classe UserCreationRequest { funzione pubblica __construct( stringa di sola lettura pubblica $Username, stringa di sola lettura pubblica $Password ) {} }

Le proprietà sono accessibili pubblicamente ma immutabili. In combinazione con la promozione delle proprietà del costruttore, le proprietà di sola lettura promettono di ridurre notevolmente il codice standard, consentendoti di scrivere classi utili più rapidamente.

readonly aiuta anche la leggibilità del codice e indica meglio le tue intenzioni. Chiunque legga o modifichi la classe UserCreationRequest sa che le sue proprietà non sono destinate a cambiare. Nel primo esempio, non è noto se altro codice nel progetto modifica direttamente le proprietà della classe. Il secondo esempio è un po' più chiaro, ma potrebbe comunque indurre uno sviluppatore a implementare i metodi ridondanti setUsername() e setPassword().

Conclusione

Il modificatore readonly porta supporto di immutabilità integrato alle proprietà della classe PHP. Rende il tuo codice più chiaro e previene modifiche involontarie del valore imponendo l'immutabilità in fase di esecuzione.

Pubblicità

Ripensando alla serie di versioni di PHP 7, creando una classe di base simile a una struttura utilizzata per coinvolgere la definizione di proprietà digitate, scrivendo un costruttore che imposta quelle proprietà e quindi aggiungendo metodi getter per esporre i loro valori. Con PHP 8.1, puoi condensare tutto ciò in una singola firma del costruttore combinando la sola lettura pubblica e la promozione della proprietà.

Le proprietà di sola lettura sono implementate nelle ultime build di sviluppo di PHP 8.1. La versione pronta per la produzione arriverà a novembre del 2021.