# Programmazione a oggetti in PHP

> Programmazione a oggetti in PHP: classi, interfacce, trait ed enum, le novità del linguaggio da PHP 8.0 a 8.4 e il legame con deserializzazione e sicurezza.

Fonte: https://phpsos.de/it/php/objektorientierung/  
Stato: 25/10/2026  
Fornitore: PHP SOS, Assistenza di emergenza PHP e sicurezza dei server. Assistenza immediata su WhatsApp: https://wa.me/491736494914?text=Buongiorno%20PHP%20SOS%2C%20abbiamo%20bisogno%20di%20aiuto%20con%20il%20nostro%20server%20PHP.%20Azienda%3A%20%E2%80%A6%20Sito%20web%3A%20%E2%80%A6

**In breve:** la programmazione orientata agli oggetti (OOP) raggruppa i dati e le relative funzioni in classi. PHP offre a questo scopo classi, classi astratte, interfacce, trait e, da PHP 8.1, enum. Con PHP da 8.0 a 8.4 sono stati aggiunti molti strumenti del linguaggio, come la constructor promotion, `readonly`, i property hook e la visibilità asimmetrica. Per la sicurezza è importante: il codice ben incapsulato è più facile da verificare, e i metodi magici rendono pericolosa la deserializzazione non sicura. Contro le vulnerabilità nell'interprete come PHP2Shell la OOP non aiuta.

## Che cosa significa programmazione a oggetti in PHP

Invece di usare funzioni sparse e variabili globali, una classe descrive un elemento del mondo reale: un ordine, un cliente, una fattura. Stabilisce quali dati ne fanno parte (proprietà) e che cosa si può fare con essi (metodi). Un oggetto è un esemplare concreto di quella classe.

Per chi decide ha un valore pratico: il codice orientato agli oggetti con classi chiare si lascia testare, verificare e passare a fornitori di servizi con maggiore facilità. Le vecchie applicazioni PHP fatte di molti singoli script con variabili globali sono invece difficili da mantenere e soggette a errori negli upgrade.

Un'idea centrale è l'incapsulamento: una classe rende accessibili all'esterno solo i metodi che altri servono davvero e protegge il proprio stato interno. Un ordine, ad esempio, si può allora contrassegnare come pagato solo tramite un metodo che prima verifica se ciò sia lecito. Concentrare queste regole in un unico punto è un vantaggio anche per la sicurezza.

## Gli elementi di base in sintesi

| Elemento | Scopo | Esempio breve |
|---|---|---|
| Classe | modello per oggetti con proprietà e metodi | `class Rechnung { ... }` |
| Classe astratta | base comune, non istanziabile direttamente | `abstract class Zahlart { ... }` |
| Interfaccia | contratto: quali metodi una classe deve offrire | `interface Versandfaehig { ... }` |
| Trait | metodi riutilizzabili per classi senza classe genitore comune | `trait MitZeitstempel { ... }` |
| Enum | insieme fisso di valori ammessi come tipo proprio, da PHP 8.1 | `enum Status { case Offen; ... }` |

Le visibilità (`public`, `protected`, `private`) regolano chi può accedere a proprietà e metodi. Le classi sono organizzate in namespace e caricate tramite un autoloader; come funziona lo mostra la pagina [Namespace e autoloading](https://phpsos.de/it/php/namespaces-autoloading/).

## PHP moderno: le novità da 8.0 a 8.4

Gli strumenti del linguaggio che seguono sono documentati nel manuale PHP e negli annunci di rilascio:

| Versione | Novità |
|---|---|
| 8.0 | constructor promotion, operatore nullsafe `?->`, `::class` sugli oggetti |
| 8.1 | proprietà `readonly`, enum, `new` negli inizializzatori, `final` per le costanti di classe |
| 8.2 | classi `readonly`; le proprietà dinamiche sono considerate deprecate |
| 8.3 | attributo `#[\Override]`, costanti di classe tipizzate |
| 8.4 | property hook, visibilità asimmetrica, `new` senza parentesi di racchiusura |

Un esempio che combina più di questi strumenti:

```php
<?php
declare(strict_types=1);

enum Status: string
{
    case Offen = 'offen';
    case Bezahlt = 'bezahlt';
}

final class Bestellung
{
    public function __construct(
        public readonly int $id,
        public private(set) Status $status = Status::Offen,  // da PHP 8.4
    ) {}

    public function alsBezahltMarkieren(): void
    {
        $this->status = Status::Bezahlt;
    }
}

$b = new Bestellung(42);
$b->alsBezahltMarkieren();
echo $b->status->value;              // bezahlt
$s = Status::tryFrom('storniert');   // null invece di un errore
```

`readonly` impedisce che l'ID venga modificato dopo la creazione. `private(set)` consente la lettura dall'esterno, ma la scrittura solo all'interno della classe. Garanzie di questo tipo nel codice rendono meno probabili gli errori che altrimenti emergono solo in esercizio. I tipi sottostanti li spiega la pagina [Il sistema dei tipi di PHP](https://phpsos.de/it/php/typsystem/).

### Insidie degli upgrade nel codice orientato agli oggetti

Per le applicazioni più vecchie due modifiche sono particolarmente rilevanti. Da PHP 8.2.0 la creazione di proprietà dinamiche è deprecata, cioè di proprietà non dichiarate nella classe, a meno che la classe non porti l'attributo `#[\AllowDynamicProperties]`. Il codice più vecchio lo fa spesso senza accorgersene e riempie poi i log di segnalazioni. Inoltre, secondo il manuale, le proprietà tipizzate devono essere inizializzate prima della prima lettura, altrimenti PHP genera un `Error`.

Utile è l'attributo `#[\Override]` di PHP 8.3: contrassegna un metodo come sovrascrittura di un metodo della classe genitore. Se quel metodo non esiste più, ad esempio dopo una ridenominazione in una libreria, PHP segnala un errore invece di lasciare che il metodo giri a vuoto in silenzio. Controlli di questo tipo rendono gli upgrade più pianificabili; per i vecchi progetti bloccati è utile la nostra [migrazione a una versione di PHP supportata](https://phpsos.de/it/leistungen/php-migration-legacy/).

## Oggetti e memoria

In PHP gli oggetti vengono passati tramite identificatori (handle). Se si passa un oggetto a una funzione, questa lavora con lo stesso oggetto, non con una copia. È efficiente, ma porta facilmente a riferimenti circolari, ad esempio quando un ordine conosce le sue posizioni e ogni posizione conosce di nuovo il proprio ordine. Cicli di questo tipo non vengono ripuliti dal solo conteggio dei riferimenti; per questo PHP ha un proprio garbage collector. I dettagli sono nella pagina [Gestione della memoria in PHP](https://phpsos.de/it/php/speicherverwaltung/).

## OOP e sicurezza: metodi magici e deserializzazione

PHP conosce metodi magici che vengono richiamati automaticamente, come `__construct`, `__destruct`, `__toString`, `__get` o `__wakeup`. È pratico, ma ha un lato oscuro: se un'applicazione riconverte in oggetti, con `unserialize()`, dati provenienti dall'esterno, un aggressore può stabilire quali classi vengano create e così attivare codice esistente nei metodi magici. Come evitarlo lo descrive la guida [Deserializzazione non sicura in PHP](https://phpsos.de/it/ratgeber/deserialisierung-php/). In breve: per lo scambio di dati usare `json_encode()` e `json_decode()` e impiegare `unserialize()` solo per dati propri e attendibili, idealmente con l'opzione `allowed_classes`.

Contro PHP2Shell, invece, un buon codice orientato agli oggetti non aiuta. CVE-2026-109618 e CVE-2026-109619 si trovano nell'interprete, e con mod_php, secondo il team PHP, è stato dimostrato un exploit prima che giri il codice dell'applicazione. È obbligatorio l'aggiornamento a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 e il riavvio di tutti i processi PHP.

## Come aiuta concretamente PHP SOS?

- Valutiamo la struttura della Sua applicazione e mostriamo quali parti rendono più difficile un upgrade a una versione di PHP supportata.
- Cerchiamo in modo mirato schemi a rischio, come `unserialize()` su dati esterni e metodi magici pericolosi.
- Verifichiamo gli sviluppi interni nell'ambito di un [audit di sicurezza e penetration test](https://phpsos.de/it/leistungen/sicherheitsaudit-penetrationstest/).
- Installiamo l'aggiornamento di PHP, riavviamo tutti i worker e testiamo poi l'applicazione.


## Domande frequenti

**PHP è un linguaggio orientato agli oggetti?**  
PHP supporta sia il codice procedurale sia quello orientato agli oggetti. Framework, nuclei dei CMS e sistemi di shop sono oggi però costruiti per lo più a oggetti, con classi, interfacce e namespace.

**Qual è la differenza tra interfaccia e classe astratta?**  
Un'interfaccia descrive soltanto quali metodi una classe deve offrire. Una classe astratta può contenere anche codice e proprietà, ma non può essere istanziata direttamente. Una classe può avere più interfacce, ma una sola classe genitore.

**Da quando esistono gli enum in PHP?**  
Le enumerazioni sono arrivate con PHP 8.1. Sostituiscono gli insiemi di costanti con un tipo proprio che ammette solo i casi definiti. I backed enum hanno inoltre un valore int o string.

**Perché i metodi magici sono rilevanti per la sicurezza?**  
Metodi come __destruct o __wakeup vengono richiamati automaticamente da PHP, ad esempio nella deserializzazione dei dati. Se dati esterni arrivano a unserialize() senza controllo, possono innescare sequenze impreviste nelle classi esistenti.

## Fonti

- [Manuale PHP: classi e oggetti, concetti di base](https://www.php.net/manual/de/language.oop5.basic.php)
- [Manuale PHP: proprietà](https://www.php.net/manual/en/language.oop5.properties.php)
- [Manuale PHP: visibilità](https://www.php.net/manual/en/language.oop5.visibility.php)
- [Rilascio di PHP 8.1](https://www.php.net/releases/8.1/en.php)
