PHP 8 — OOP: Classi e Oggetti

class, ->, constructor promotion, extends, interfacce · PHP 8.5 · Marco Consiglio
Volta Institute · Napoli
A.A. 2026
🏗️ Cos'è una classe — un modello per creare oggetti
Come già visto nella guida JavaScript sulle Classi, una class è un modello per creare più oggetti (istanze) che condividono struttura e comportamento. In PHP la sintassi è molto simile.
<?php class Studente { public string $nome; public string $corso; public function __construct(string $nome, string $corso) { $this->nome = $nome; $this->corso = $corso; } } $marco = new Studente("Marco", "Full Stack"); echo $marco->nome; // → Marco ?>
⚠️ Sintassi diversa da JavaScript: il metodo speciale si chiama __construct() (con doppio underscore, non semplicemente "constructor"), e per accedere a proprietà/metodi si usa la freccia -> invece del punto . di JavaScript.
⚙️ Metodi — azioni condivise da tutte le istanze
<?php class Studente { public string $nome; public array $voti = []; public function __construct(string $nome) { $this->nome = $nome; } public function aggiungiVoto(int $voto): void { $this->voti[] = $voto; } public function calcolaMedia(): float { if (empty($this->voti)) return 0; return array_sum($this->voti) / count($this->voti); } } $marco = new Studente("Marco"); $marco->aggiungiVoto(28); $marco->aggiungiVoto(30); echo $marco->calcolaMedia(); // → 29 ?>
💡 : void come tipo di ritorno indica che la funzione non restituisce alcun valore utilizzabile — usato spesso per metodi che modificano lo stato dell'oggetto (come aggiungiVoto) senza restituire nulla.
✨ Constructor property promotion (PHP 8.0+) — la novità che semplifica tutto
Una delle innovazioni più apprezzate di PHP 8: puoi dichiarare e assegnare le proprietà direttamente nella firma del constructor, eliminando il codice ripetitivo visto nell'esempio precedente.
<?php // PRIMA di PHP 8 (o senza promotion) — molto codice ripetitivo: class Prodotto { public string $nome; public float $prezzo; public function __construct(string $nome, float $prezzo) { $this->nome = $nome; $this->prezzo = $prezzo; } } // CON constructor property promotion (PHP 8+) — identico risultato, molto più conciso: class Prodotto { public function __construct( public string $nome, public float $prezzo ) {} } $mouse = new Prodotto("Mouse", 15.99); echo $mouse->nome; // → Mouse (la proprietà esiste già, senza righe extra nel corpo!) ?>
✅ Aggiungendo public (o private/protected) direttamente davanti al parametro del constructor, PHP dichiara automaticamente la proprietà E la assegna — eliminando 4 righe di codice ripetitivo per ogni proprietà.
🧬 Ereditarietà — extends
Come nella guida JavaScript sulle Classi, extends permette a una classe di ereditare proprietà e metodi da un'altra.
<?php class Persona { public function __construct(protected string $nome) {} public function presentati(): void { echo "Sono {$this->nome}"; } } class Studente extends Persona { public function __construct(string $nome, private string $corso) { parent::__construct($nome); // chiama il constructor della classe GENITORE } } $marco = new Studente("Marco", "Full Stack"); $marco->presentati(); // → Sono Marco (metodo EREDITATO da Persona, mai riscritto in Studente!) ?>
⚠️ Sintassi diversa da JavaScript: per chiamare il constructor del genitore si usa parent::__construct() (con i due punti doppi ::), non semplicemente super() come in JavaScript.
🔒 public, private, protected — i tre livelli di visibilità
ModificatoreAccessibile da...
publicOvunque: dentro la classe, nelle sottoclassi, e dall'esterno
protectedDentro la classe stessa e nelle sue sottoclassi (extends), MA non dall'esterno
privateSolo dentro la classe stessa — nemmeno le sottoclassi possono accedervi direttamente
<?php class ContoBancario { public function __construct(private float $saldo) {} public function deposita(float $importo): void { $this->saldo += $importo; } public function controllaSaldo(): float { return $this->saldo; } } $conto = new ContoBancario(100); $conto->deposita(50); echo $conto->controllaSaldo(); // → 150 // echo $conto->saldo; // ❌ Errore! $saldo è private, non accessibile dall'esterno ?>
💡 Questo è l'equivalente PHP dei campi privati #saldo visti nella guida JavaScript sulle Classi — stesso principio di incapsulamento, sintassi diversa (una keyword invece di un simbolo).
🧩 Interfacce — un contratto che le classi devono rispettare
Un'interfaccia definisce quali metodi una classe DEVE implementare, senza fornirne il codice — un "contratto" che garantisce che classi diverse offrano lo stesso insieme minimo di funzionalità.
<?php interface Notificabile { public function invia(string $messaggio): bool; } class NotificaEmail implements Notificabile { public function invia(string $messaggio): bool { echo "Email inviata: $messaggio"; return true; } } // Qualsiasi classe "implements Notificabile" DEVE avere un metodo invia() con questa firma ?>
✅ Le interfacce sono utili nei progetti più grandi (come i CMS/CRM delle guide successive) per garantire che, ad esempio, tutti i "canali di notifica" (email, SMS, push) offrano lo stesso metodo invia(), permettendo di scambiarli senza modificare il codice che li usa.
🔐 readonly (PHP 8.1+) — proprietà immutabili dopo l'inizializzazione
<?php class Ordine { public function __construct( public readonly string $codice, public readonly float $totale ) {} } $ordine = new Ordine("ORD-001", 59.97); echo $ordine->codice; // → ORD-001 // $ordine->codice = "ORD-002"; // ❌ Errore! readonly impedisce la modifica dopo l'inizializzazione ?>
💡 readonly garantisce che un valore, una volta impostato nel constructor, non possa più essere modificato — utile per dati che per natura non dovrebbero mai cambiare (un codice ordine, un ID univoco, una data di creazione).