# Namespace e autoloading (PSR-4)

> Namespace e autoloading in PHP con PSR-4: dal nome della classe al percorso del file, spl_autoload_register, autoloader di Composer e verifica dopo un incidente.

Fonte: https://phpsos.de/it/php/namespaces-autoloading/  
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:** in PHP i namespace sono una sorta di cartelle per i nomi delle classi: `App\Rechnung\Pdf` e `Bibliothek\Pdf` possono coesistere senza darsi fastidio. L'autoloading fa sì che PHP carichi una classe solo quando serve per la prima volta. Lo standard PSR-4 stabilisce come da un nome di classe si ricavi un percorso di file; Composer genera poi l'autoloader adatto. Poiché questo autoloader viene eseguito a ogni richiesta, dopo un incidente di sicurezza è tra le prime cose da controllare.

## Perché PHP ha bisogno dei namespace

I namespace esistono dalla versione PHP 5.3.0. Prima, tutte le classi e le funzioni condividevano un unico spazio dei nomi globale. Se due librerie si chiamavano `Logger`, si andava a sbattere. Gli sviluppatori si aiutavano con nomi lunghi come `Firma_Modul_Unterbereich_Logger`.

Il manuale PHP indica due problemi che i namespace risolvono: le collisioni di nomi tra il codice proprio, le classi interne di PHP e le librerie di terze parti, e i nomi eccessivamente lunghi nati solo per aggirare tali collisioni. Per chi decide significa: solo i namespace hanno reso praticabile combinare decine di pacchetti esterni in un progetto, come oggi è consueto con [Composer](https://phpsos.de/it/php/composer/).

## I namespace nella pratica: namespace, use, alias

Un file dichiara il proprio namespace nella prima istruzione. Con `use` si importano classi da altri namespace, se si vuole con un nome più breve.

```php
<?php
declare(strict_types=1);

namespace App\Rechnung;

use App\Kunde\Kunde;
use Psr\Log\LoggerInterface as Log;

final class PdfErzeuger
{
    public function __construct(private Log $log) {}

    public function erzeugen(Kunde $kunde): string
    {
        $this->log->info('PDF erzeugt', ['kunde' => $kunde->id]);
        return \sprintf('Rechnung für %s', $kunde->name);
    }
}
```

Il nome completo di questa classe è `App\Rechnung\PdfErzeuger`. Il backslash iniziale in `\sprintf` rimanda esplicitamente alla funzione globale di PHP.

## Autoloading: caricare le classi quando servono

Senza autoloading ogni script dovrebbe includere con `require` tutti i file necessari. Con `spl_autoload_register()` si registra invece una funzione che PHP richiama non appena viene usata una classe, un'interfaccia, un trait o un enum sconosciuti. Riceve il nome della classe e carica il file corrispondente.

```php
<?php
spl_autoload_register(function (string $klasse): void {
    $praefix = 'App\\';
    $basis   = __DIR__ . '/src/';

    if (!str_starts_with($klasse, $praefix)) {
        return; // non di competenza, tocca al prossimo autoloader
    }
    $datei = $basis . str_replace('\\', '/', substr($klasse, strlen($praefix))) . '.php';
    if (is_file($datei)) {
        require $datei;
    }
});
```

`spl_autoload_register()` si può richiamare più volte. PHP interroga allora gli autoloader registrati uno dopo l'altro, finché uno ha caricato la classe. Nella pratica le grandi applicazioni ne hanno spesso più d'uno: l'autoloader di Composer per le librerie, uno proprio del CMS e altri di plugin o moduli. Per gli amministratori significa: quale codice venga effettivamente caricato in una richiesta risulta dall'interazione di tutti questi autoloader e non dalla sola struttura delle cartelle.

Il manuale sconsiglia vivamente di lanciare eccezioni in un autoloader; PSR-4 lo vieta espressamente. La più vecchia funzione `__autoload()` è stata dichiarata deprecata con PHP 7.2.0 e rimossa con PHP 8.0.0.

## PSR-4: dal nome della classe al percorso del file

PSR-4 è uno standard di PHP-FIG. Un nome di classe completo inizia con un namespace del produttore. Un prefisso del namespace viene associato a una directory di base, il resto del nome genera le sottocartelle, e il file termina con `.php`. Maiuscole e minuscole devono corrispondere esattamente. Così appare l'associazione nel `composer.json`:

```json
{
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

| Nome della classe | File |
|---|---|
| `App\Kunde\Kunde` | `src/Kunde/Kunde.php` |
| `App\Rechnung\PdfErzeuger` | `src/Rechnung/PdfErzeuger.php` |
| `App\Rechnung\Pdf\Vorlage` | `src/Rechnung/Pdf/Vorlage.php` |

Un classico inciampo è la distinzione tra maiuscole e minuscole. Sui computer di sviluppo con Windows o macOS il file system spesso non distingue tra `Kunde.php` e `kunde.php`, su un server Linux sì. Un'applicazione che gira in locale non trova allora una classe sul server. La regola di PSR-4 di usare i nomi esattamente con la grafia corretta evita queste sorprese al momento del rilascio.

Oltre a `psr-4`, Composer conosce `classmap` per il codice senza struttura standard e `files` per i file che vengono caricati a ogni richiesta, ad esempio funzioni di utilità. Altri standard di PHP-FIG sono descritti nella pagina [Standard PSR](https://phpsos.de/it/php/psr-standards/).

## Ottimizzare l'autoloader in produzione

In produzione l'autoloader è meglio che non cerchi più nel file system, ma consulti un elenco già pronto. Composer offre a questo scopo due livelli:

1. `composer install --no-dev --optimize-autoloader` trasforma le regole PSR-4 in un elenco di classi. Secondo la documentazione di Composer è raccomandato per la produzione.
2. `--classmap-authoritative` va oltre: le classi vengono caricate esclusivamente dall'elenco. I file non elencati l'autoloader non li carica affatto.
3. A ogni rilascio l'elenco viene rigenerato, in modo che le nuove classi vengano trovate.

## Autoloading e sicurezza dopo PHP2Shell

PHP2Shell riguarda l'interprete PHP, non l'autoloader. Restano obbligatori l'aggiornamento a PHP 8.5.12, 8.4.27, 8.3.36 o 8.2.35 e il riavvio di tutti i worker. Dopo un possibile incidente, però, l'autoloader merita particolare attenzione: `vendor/autoload.php` e tutti i file registrati sotto `files` vengono eseguiti a ogni richiesta. Una riga lì inserita agisce quindi su tutto il sito web, senza che nella cartella di upload ci sia un nuovo file appariscente.

Verifichi perciò se `vendor` e i file di autoload corrispondono allo stato controllato presente nel controllo di versione. Sono utili gli articoli [Trovare i file modificati di recente](https://phpsos.de/it/blog/geaenderte-dateien-finden/) e [Confrontare i file del nucleo del CMS con l'originale](https://phpsos.de/it/blog/cms-kerndateien-vergleichen/). Nel dubbio, un `vendor` rigenerato da zero a partire dal file di lock è più sicuro di qualsiasi riparazione puntuale.

## Come aiuta concretamente PHP SOS?

- Confrontiamo `vendor`, autoloader e file di ingresso con lo stato controllato e contrassegniamo ogni scostamento.
- Ripristiniamo l'insieme dei pacchetti dal file di lock e configuriamo un autoloader ottimizzato.
- Verifichiamo che nel webroot si trovi solo la cartella pubblica e che il codice sorgente non sia raggiungibile direttamente tramite URL.
- In caso di compromissione ci occupiamo della bonifica nell'ambito della [rimozione del malware](https://phpsos.de/it/leistungen/malware-entfernung/) e documentiamo il risultato.


## Domande frequenti

**Da quando esistono i namespace in PHP?**  
Da PHP 5.3.0. Secondo il manuale risolvono due problemi: le collisioni di nomi tra il codice proprio, PHP e le librerie di terze parti, e i nomi di classe eccessivamente lunghi nati solo per evitare tali collisioni.

**Qual è la differenza tra PSR-0 e PSR-4?**  
Entrambi associano i nomi delle classi ai percorsi dei file. Con PSR-4 il prefisso del namespace non viene ripetuto nel percorso del file, il che dà directory meno profonde. PSR-0 è classificato come deprecato da PHP-FIG, PSR-4 è lo standard raccomandato.

**__autoload() funziona ancora?**  
No. __autoload() è stato dichiarato deprecato con PHP 7.2.0 e rimosso con PHP 8.0.0. Oggi gli autoloader si registrano con spl_autoload_register(), nella pratica di solito tramite l'autoloader generato da Composer.

**Devo rigenerare l'autoloader dopo aver creato una nuova classe?**  
Con sole regole PSR-4 no; secondo la documentazione di Composer è proprio questo un vantaggio di PSR-4. Chi in produzione usa un elenco ottimizzato delle classi deve rigenerarlo a ogni rilascio.

## Fonti

- [PHP-FIG: autoloader PSR-4](https://www.php-fig.org/psr/psr-4/)
- [Manuale PHP: namespace, panoramica](https://www.php.net/manual/de/language.namespaces.rationale.php)
- [Manuale PHP: autoloading](https://www.php.net/manual/de/language.oop5.autoload.php)
- [Composer: lo schema di composer.json](https://getcomposer.org/doc/04-schema.md)
