Ogni guida a un problema di PHP comincia con "attiva display_errors". Su un sito in produzione quello stampa i suoi percorsi di file, il suo framework, a volte il nome del suo database, a chiunque riesca a far andare la pagina in errore - compreso chi ci sta appunto provando.

Le impostazioni giuste per la produzione

display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/mysite-error.log
error_reporting = E_ALL & ~E_DEPRECATED

E_ALL senza le deprecazioni tiene il log leggibile su una base di codice vecchia e continua comunque a registrare tutto ciò che è davvero sbagliato.

Lo guardi mentre riproduce il problema

tail -f /var/log/php/mysite-error.log

Lasci quello in esecuzione e carichi la pagina rotta. Ottiene le stesse informazioni che display_errors avrebbe mostrato, nello stesso istante, senza che nessun visitatore le veda mai.

Se proprio deve vederlo nel browser

Lo mostri soltanto a sé, per indirizzo:

if ((@$_SERVER["REMOTE_ADDR"] ?? "") === "YOUR.IP.HERE") {
    ini_set("display_errors", "1");
    error_reporting(E_ALL);
}
Metta quello dietro un controllo che non può dimenticarsi di togliere: una costante in un file di configurazione che non viene distribuito, non una riga commentata. Una riga commentata prima o poi viene scommentata.

Un log che cresce troppo in fretta

sort /var/log/php/mysite-error.log | uniq -c | sort -rn | head -5

Un avviso a ogni richiesta scrive gigabyte in un giorno. La prima riga di quell'output è quasi sempre tutto il problema.

Riattivi le deprecazioni per un giorno prima di un aggiornamento di PHP. Sono gli avvisi che nella versione successiva diventano errori, e leggerli per tempo è la preparazione più economica che ci sia.