Introduzione
Una delle novità più utili introdotte nelle versioni recenti di PHP è la promozione delle proprietà nel costruttore (constructor property promotion). Si tratta di una feature pensata per ridurre il codice ripetitivo quando una classe deve ricevere dei valori tramite il costruttore e salvarli come proprietà dell’oggetto.
Prima di questa novità, in PHP era molto comune scrivere tre passaggi separati: dichiarare le proprietà della classe, accettare i parametri nel costruttore e assegnare manualmente i valori alle proprietà. Con la promozione delle proprietà, tutto questo si compatta in una sintassi più breve, chiara e leggibile.
Questa feature è particolarmente utile in classi che rappresentano dati, configurazioni, DTO, servizi semplici e oggetti di dominio. Non è solo una comodità estetica: aiuta anche a scrivere codice più coerente e meno soggetto a errori di distrazione, come dimenticare un’assegnazione nel costruttore.
Codice completo
<?php
declare(strict_types=1);
class Product
{
public function __construct(
private int $id,
private string $name,
private float $price,
private ?string $description = null
) {
}
public function getId(): int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function getPrice(): float
{
return $this->price;
}
public function getDescription(): ?string
{
return $this->description;
}
public function getLabel(): string
{
return $this->name . ´ - €´ . number_format($this->price, 2, ´,´, ´.´);
}
}
class ProductRepository
{
/** @var Product[] */
private array $products = [];
public function add(Product $product): void
{
$this->products[$product->getId()] = $product;
}
public function findById(int $id): ?Product
{
return $this->products[$id] ?? null;
}
}
// Uso della classe
$product = new Product(
id: 1,
name: ´Tastiera meccanica´,
price: 89.90,
description: ´Tastiera con switch blu e retroilluminazione RGB´
);
$repository = new ProductRepository();
$repository->add($product);
$found = $repository->findById(1);
if ($found !== null) {
echo $found->getLabel();
echo PHP_EOL;
echo $found->getDescription();
} Spiegazione
Nel codice precedente, la classe Product usa la promozione delle proprietà nel costruttore. Questo significa che i parametri del costruttore diventano automaticamente proprietà dell’oggetto grazie alla presenza di private davanti al tipo e al nome del parametro.
Confrontiamo mentalmente questo approccio con quello tradizionale. Senza promozione, avremmo dovuto scrivere qualcosa del genere:
- dichiarazione delle proprietà nella classe;
- parametri nel costruttore;
- assegnazioni come $this->id = $id;
- ripetizione per ogni campo.
Con la nuova sintassi, invece, tutto si concentra nel costruttore. Il risultato è un codice più compatto e più facile da leggere, soprattutto quando la classe ha molte proprietà iniziali.
Come funziona la sintassi
Ogni parametro del costruttore può essere preceduto da un modificatore di visibilità:
- public se la proprietà deve essere accessibile dall’esterno;
- protected se deve essere accessibile solo nelle classi figlie;
- private se deve restare interna alla classe.
Nel nostro esempio, le proprietà sono private, quindi possono essere usate solo all’interno della classe Product. Per accedervi dall’esterno abbiamo creato dei metodi getter, che sono una scelta molto comune e pulita in progetti ben strutturati.
Uso dei parametri nominati
Nel punto in cui istanziamo l’oggetto, abbiamo usato anche i parametri nominati:
$product = new Product(
id: 1,
name: ´Tastiera meccanica´,
price: 89.90,
description: ´Tastiera con switch blu e retroilluminazione RGB´
); Questa è un’altra novità molto pratica delle versioni recenti di PHP. I parametri nominati migliorano la leggibilità e rendono più semplice capire il significato di ogni valore passato al costruttore, specialmente quando i parametri sono tanti o hanno tipi simili.
Valori opzionali
La proprietà $description è dichiarata come ?string e ha valore predefinito null. Questo significa che il parametro è opzionale. Se non viene passato, PHP assegna automaticamente null.
Questa soluzione è molto utile quando alcune informazioni non sono sempre disponibili. In un catalogo prodotti, ad esempio, la descrizione potrebbe essere assente per alcuni articoli.
Best practice
La promozione delle proprietà nel costruttore è semplice da usare, ma conviene seguirne alcune buone pratiche per mantenere il codice pulito e professionale.
- Usala per classi dati o oggetti semplici: è perfetta per DTO, entity leggere e servizi con poche dipendenze.
- Evita di abusarne in classi troppo complesse: se il costruttore diventa enorme, il codice resta difficile da mantenere anche con questa sintassi.
- Preferisci tipi espliciti: dichiara sempre il tipo dei parametri, ad esempio int, string, float o ?string.
- Usa proprietà private quando possibile: proteggono meglio lo stato interno dell’oggetto e favoriscono l’incapsulamento.
- Combinala con i getter solo quando servono: non creare metodi inutili, ma esponi solo ciò che serve davvero all’esterno.
- Non confonderla con l’inizializzazione logica: la promozione delle proprietà serve a dichiarare e assegnare dati, non a contenere logiche complesse.
Un buon criterio pratico è questo: se un parametro del costruttore serve solo a essere salvato in una proprietà, la promozione è quasi sempre una scelta ottima. Se invece quel parametro richiede trasformazioni, controlli complessi o calcoli aggiuntivi, può essere meglio gestirlo con assegnazioni esplicite nel corpo del costruttore.
Quando evitarla
Ci sono casi in cui la sintassi tradizionale resta più chiara. Ad esempio:
- quando il costruttore deve validare i dati prima di assegnarli;
- quando una proprietà deriva da più parametri combinati tra loro;
- quando vuoi separare chiaramente dichiarazione, logica e assegnazione.
In altre parole, la promozione delle proprietà è uno strumento per semplificare, non per nascondere la logica del programma.
Riepilogo
La promozione delle proprietà nel costruttore è una delle novità più pratiche delle versioni recenti di PHP. Ti permette di scrivere classi più concise, ridurre il boilerplate e migliorare la leggibilità del codice.
In sintesi, i vantaggi principali sono:
- meno codice ripetitivo;
- maggiore chiarezza nella definizione degli oggetti;
- integrazione naturale con i tipi e i valori opzionali;
- ottima combinazione con i parametri nominati;
- più facilità di manutenzione nei progetti moderni.
Se stai lavorando con PHP moderno, questa feature dovrebbe entrare nel tuo stile di scrittura quotidiano, soprattutto per classi semplici e ben modellate. È una novità piccola nella forma, ma molto grande nell’impatto sulla qualità del codice.
Approfondisci con risorse ufficiali
- Manuale PHP sulla sintassi dei costruttori e delle proprietà: documentazione ufficiale del linguaggio.
- PHP 8.0 Migration Guide: utile per capire le novità introdotte in questa versione.
- PHP RFC - Constructor Property Promotion: la proposta tecnica originale che spiega motivazioni e dettagli della feature.
- Documentazione sui tipi in PHP: fondamentale per usare correttamente proprietà tipizzate e valori nullabili.
