Una classe PHP si dichiara con class Name { ... } e contiene proprietà (variabili) e metodi (funzioni). new Name() crea un oggetto a partire da essa, e -> legge una proprietà o chiama un metodo: $user->name, $user->greet().
La classe è il modello, l'oggetto è una cosa costruita a partire da esso. Puoi creare da una classe tutti gli oggetti che ti servono, e ognuno ha i propri valori delle proprietà.
Proprietà e metodi
Una proprietà si dichiara con una parola chiave di visibilità, un tipo facoltativo e un valore di default facoltativo. Un metodo è una funzione dentro la classe. Dentro un metodo, $this è l'oggetto su cui il metodo è stato chiamato, quindi $this->balance legge il saldo di quell'oggetto.
Ogni oggetto mantiene il proprio $balance: versare in $a non tocca $b. Impostare le proprietà una per una dopo new diventa noioso; un costruttore riceve invece i valori iniziali come argomenti.
public, private e protected
La visibilità controlla chi può accedere a una proprietà o chiamare un metodo:
| Parola chiave | Accessibile da |
|---|---|
public | ovunque |
protected | la classe stessa e le classi che la estendono |
private | solo la classe che lo dichiara |
Rendere una proprietà private ed esporre dei metodi è il modo in cui una classe protegge le proprie regole. Qui il saldo può cambiare solo tramite deposit() e withdraw(), che rifiutano importi non validi:
Leggere la proprietà privata dall'esterno della classe non è un warning, è un Error:
Proprietà tipizzate e valori non inizializzati
Una proprietà tipizzata senza valore di default parte non inizializzata, che è diverso da null. Leggerla prima che le venga assegnato qualcosa lancia un Error. Dalle un default, assegnala nel costruttore, oppure rendila nullable con ?Type e = null.
I tipi vengono imposti all'assegnazione. Con la modalità di default (non strict), $p->stock = '7' converte la stringa numerica in 7, mentre $p->stock = 'many' lancia un TypeError.
Proprietà readonly
Una proprietà readonly (PHP 8.1) si può scrivere una volta, dall'interno della classe, e poi mai più. È il modo consueto per costruire oggetti valore come importi di denaro o ID. PHP 8.2 ha aggiunto readonly class, che rende readonly ogni proprietà.
Una proprietà readonly deve avere un tipo e non può avere un valore di default. Se ti serve una copia modificata, crea un nuovo oggetto (new Order('B-2002')) invece di modificare quello vecchio.
Stampare un oggetto con __toString
echo $object funziona solo quando la classe definisce __toString(). Il metodo restituisce la stringa che PHP deve usare ogni volta che l'oggetto viene trattato come testo: in echo, nella concatenazione di stringhe, in "{$object}".
Senza __toString, echo $object lancia un Error ("Object of class Money could not be converted to string"). Per il debug, print_r() e var_dump() funzionano su qualsiasi oggetto e mostrano anche le proprietà private; vedi var_dump e print_r.
Assegnare un oggetto non lo copia
È l'errore che colpisce di più chi arriva dagli array. Assegnare un array lo copia. Assegnare un oggetto copia solo l'handle: entrambe le variabili puntano allora allo stesso oggetto.
clone fa una copia superficiale: se una proprietà contiene un altro oggetto, entrambe le copie condividono ancora quell'oggetto interno. === è vero solo per lo stesso oggetto, mentre == confronta i valori delle proprietà di due oggetti della stessa classe. Passare un oggetto a una funzione funziona come l'assegnazione, quindi una funzione può modificare l'oggetto che riceve.
Domande frequenti
Come creo un oggetto da una classe in PHP?
Usa new con il nome della classe: $user = new User();. Se la classe ha un costruttore, passa i suoi argomenti tra le parentesi, come in new User('Ada'). Poi chiami i metodi e leggi le proprietà con l'operatore freccia: $user->name, $user->greet().
Cosa significa $this in PHP?
$this è l'oggetto su cui è stato chiamato il metodo corrente. Dentro $ada->greet(), $this è $ada, quindi $this->name legge il nome di Ada. Esiste solo dentro i metodi non statici.
Qual è la differenza tra public, private e protected in PHP?
I membri public si possono usare da qualsiasi punto, i membri private solo dall'interno della classe che li dichiara, e i membri protected da quella classe e dalle sue classi figlie. Leggere una proprietà privata dall'esterno lancia un Error: Cannot access private property.
In PHP gli oggetti vengono passati per riferimento?
Una variabile contiene un riferimento (handle) all'oggetto, non l'oggetto stesso. $b = $a; copia l'handle, quindi entrambe le variabili puntano allo stesso oggetto e una modifica tramite $b si vede in $a. Usa $b = clone $a; per avere una copia indipendente.
Cos'è una proprietà readonly in PHP?
Una proprietà dichiarata public readonly string $id; (PHP 8.1+) si può impostare una volta, dall'interno della classe, e non si può più modificare in seguito. Scriverci una seconda volta lancia un Error: Cannot modify readonly property.