W3docs

error_reporting()

Scopri come PHP gestisce la segnalazione degli errori con error_reporting(), display_errors e log_errors per sviluppo e produzione.

Introduzione

Questo capitolo illustra come PHP segnala gli errori: la funzione error_reporting() che controlla quali errori PHP genera, le direttive display_errors e log_errors che controllano dove vengono inviati, e le funzioni di supporto per gestirli e registrarli. Al termine saprai come configurare la segnalazione degli errori in modo diverso per lo sviluppo e la produzione, e perché configurarla in modo errato è uno degli errori di sicurezza e debug più comuni in PHP.

Perché la segnalazione degli errori è importante

PHP è un linguaggio dinamicamente tipizzato e permissivo: molti errori che bloccherebbero la compilazione in altri linguaggi emergono invece a runtime come avvisi, notifiche o messaggi di deprecazione. Se li sopprimi, comportamenti errati possono arrivare silenziosamente in produzione. Se li mostri agli utenti finali, rischi di rivelare percorsi di file, SQL e stack trace agli aggressori.

Una buona segnalazione degli errori trova il giusto equilibrio per ciascun ambiente:

  • In sviluppo — mostra tutto, chiaramente, così individui i bug mentre scrivi.
  • In produzione — non mostrare nulla all'utente, ma registra tutto in un file per analisi successive.

Livelli di errore e costanti

Gli errori PHP sono classificati per livello. Ogni livello è una costante predefinita e si combinano con gli operatori bit a bit. I livelli più comuni:

CostanteSignificato
E_ERRORErrore fatale a runtime; l'esecuzione dello script si interrompe.
E_WARNINGAvviso a runtime; lo script continua.
E_NOTICENotifica (ad es. uso di una variabile non definita).
E_DEPRECATEDUso di una funzionalità che sarà rimossa in una futura versione di PHP.
E_USER_ERROR / E_USER_WARNING / E_USER_NOTICELivelli che puoi generare tu stesso con trigger_error().
E_ALLTutti gli errori, avvisi e notifiche.

Poiché sono flag bit, si combinano con | (inclusione), & (maschera) e ~ (negazione):

// All errors EXCEPT notices and deprecation messages
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);

// Only fatal errors and warnings
error_reporting(E_ERROR | E_WARNING);

Nota sulla versione: Da PHP 8.0 il livello predefinito di error_reporting è E_ALL. E_STRICT è stato deprecato in 8.0 e rimosso in 8.4, e le sue notifiche sono ora incluse in E_ALL, quindi non è più necessario aggiungerlo separatamente.

Segnalazione vs. visualizzazione: due impostazioni distinte

Una fonte frequente di confusione è che due interruttori indipendenti decidono se un errore viene effettivamente mostrato:

  1. error_reporting() — decide quali livelli PHP genera.
  2. display_errors — decide se gli errori generati vengono stampati nell'output.

Devi attivare entrambi per vedere un errore sullo schermo. L'esempio seguente genera una notifica di livello E_ALL e la stampa perché entrambi gli interruttori sono attivi:

<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');

echo $undefined;   // Warning: Undefined variable $undefined

Se display_errors fosse disattivato, la stessa notifica verrebbe comunque generata (e potrebbe essere registrata), ma non apparirebbe nell'output della pagina.

Le funzioni principali per la segnalazione degli errori

error_reporting()

Imposta quali livelli di errore vengono segnalati a runtime e restituisce il livello precedente. Chiamala senza argomenti per leggere l'impostazione corrente.

<?php
$old = error_reporting(E_ALL & ~E_NOTICE);
echo "Now reporting all errors except notices.\n";
echo "Previous level was: " . $old . "\n";

ini_set()

Sovrascrive una direttiva di php.ini per la durata dello script corrente. È l'equivalente a runtime della modifica di php.ini, ed è il modo per attivare display_errors, display_startup_errors e log_errors dall'interno del codice.

<?php
// Development setup: show everything on screen
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);

Nota: display_errors non può intercettare gli errori fatali di parsing nello stesso file, perché l'intero file non riesce a compilarsi prima che ini_set() venga eseguita. Per questi casi, imposta la direttiva direttamente in php.ini.

set_error_handler()

Registra un callback che viene eseguito ogni volta che viene generato un errore (non fatale), permettendoti di sostituire il comportamento predefinito di PHP — ad esempio per convertire gli avvisi in eccezioni o per formattarli come JSON per un'API. Il callback riceve il livello di errore, il messaggio, il file e la riga.

<?php
set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline): bool {
    echo "[$errno] $errstr in " . basename($errfile) . " on line $errline\n";
    return true; // true = we handled it; PHP's internal handler is skipped
});

echo $undefined; // routed to our handler instead of the default message

Vedi set_error_handler() per la firma completa e come ripristinare il gestore precedente.

error_log() e trigger_error()

  • error_log() invia un messaggio al log configurato di PHP, a un file specifico o a un indirizzo email — mai all'output della pagina. Questo è il modo sicuro per la produzione di registrare i problemi.
  • trigger_error() genera un errore definito da te (livelli E_USER_*), che poi scorre attraverso la stessa pipeline di error_reporting/gestore degli errori integrati.
<?php
// Append a message to a specific log file (message type 3)
error_log("Payment gateway timed out", 3, "/var/log/php_errors.log");

// Raise a user-level warning that your handler / log can pick up
trigger_error("Cache miss for product 42", E_USER_WARNING);

Approfondisci in error_log() e trigger_error().

Configurazione consigliata per ambiente

Anziché distribuire le impostazioni ovunque, inseriscile in cima al file di bootstrap.

<?php
// --- Development ---
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
<?php
// --- Production ---
error_reporting(E_ALL);          // still GENERATE everything...
ini_set('display_errors', '0');  // ...but never show it to users...
ini_set('log_errors', '1');      // ...log it instead.
ini_set('error_log', '/var/log/php_errors.log');

Il blocco di produzione mantiene la piena visibilità tramite i log senza esporre nulla ai visitatori — la configurazione che quasi sempre si desidera su un server live.

Best practice

  • Non eseguire mai in produzione con display_errors attivo. Percorsi e stack trace esposti costituiscono un rischio di divulgazione di informazioni.
  • Segnala sempre con E_ALL ovunque. Segnalazione e visualizzazione sono separate; sopprimere i livelli nasconde solo i bug.
  • Evita l'operatore di soppressione degli errori @. Nasconde gli errori nel punto di chiamata e rende il debug molto più difficile; gestisci esplicitamente la condizione.
  • Cattura ciò che puoi come eccezioni. Per i fallimenti recuperabili, preferisci try/catch ai gestori di errori. Vedi PHP Exceptions.
  • Usa una libreria di logging nelle app più grandi. Strumenti come Monolog offrono livelli di log, rotazione e destinazioni multiple su error_log().

Conclusione

La segnalazione degli errori in PHP si articola in tre livelli: scegliere i livelli con error_reporting(), scegliere la destinazione con display_errors / log_errors, e facoltativamente personalizzare la gestione con set_error_handler() e trigger_error(). Configurali deliberatamente — verbosi sullo schermo durante lo sviluppo, silenziosi ma registrati in produzione — e otterrai un debug rapido senza esporre l'applicazione a utenti o aggressori.

Letture correlate: PHP Error handling · error_get_last() · try…catch.

Esercitazione

Pratica
Cosa si può dire sulla segnalazione degli errori in PHP?
Cosa si può dire sulla segnalazione degli errori in PHP?
Was this page helpful?