Situazione attuale: PHP2Shell. Due vulnerabilità critiche di PHP (CVSS 9,2) consentono codice dannoso senza autenticazione. Patch dal 21/10/2026.Che cosa fare ora →

Namespace e autoloading (PSR-4)

I namespace ordinano il codice PHP, l'autoloading carica le classi esattamente quando servono. Qui vede come PSR-4 associa i nomi delle classi ai file e perché dopo un incidente l'autoloader va controllato.

Stato 5 min di letturaConoscere PHP

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.

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
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
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:

{
    "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.

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 e Confrontare i file del nucleo del CMS con l'originale. 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 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

Contatto immediato

Ogni ora conta. Ci scriva adesso.

Descriva brevemente sistema, versione di PHP e quanto osservato. Ci faremo sentire, chiariremo la situazione e lavoreremo da remoto fino alla chiusura e alla documentazione dell'incidente.

Aiuto immediato