debug_backtrace()
Il debug è un aspetto essenziale della programmazione PHP. Questa guida illustra i fondamenti del debug degli errori in PHP con debug_backtrace().
Quando un bug appare in profondità all'interno di chiamate a funzioni annidate, il solo messaggio di errore raramente rivela come il codice sia arrivato lì. La funzione debug_backtrace() risponde a questa domanda: restituisce un'istantanea dello stack di chiamate nel punto esatto in cui viene invocata, così puoi vedere quale funzione ha chiamato quale, in quale file e su quale riga. Questa pagina spiega la firma della funzione, la struttura dell'array restituito, i modelli pratici di utilizzo e come si inserisce accanto agli strumenti di segnalazione degli errori di PHP.
Cosa restituisce debug_backtrace()
debug_backtrace() restituisce un array di array associativi — un elemento per ogni frame dello stack, ordinati dalla chiamata più interna (dove è stata invocata) verso il punto di ingresso dello script. Non genera mai eccezioni e non interrompe mai l'esecuzione; si limita a riportare lo stack corrente.
La firma è:
debug_backtrace(int $options = DEBUG_BACKTRACE_PROVIDE_OBJECT, int $limit = 0): arrayParametri
$options(int) — una bitmask che controlla cosa include ogni frame:DEBUG_BACKTRACE_PROVIDE_OBJECT(predefinito) — include l'objecteffettivo per le chiamate ai metodi.DEBUG_BACKTRACE_IGNORE_ARGS— omette l'indiceargs, mantenendo l'output compatto ed evitando riferimenti a argomenti di grandi dimensioni.
$limit(int) — il numero massimo di frame da restituire.0(il valore predefinito) significa l'intero stack. Utile quando si necessita solo del chiamante immediato.
Ogni frame
Ogni frame è un array associativo che può contenere:
function— il nome della funzione o del metodo chiamato.line— la riga da cui è stata effettuata la chiamata.file— il file da cui è stata effettuata la chiamata.class— il nome della classe, per le chiamate ai metodi.object— l'istanza dell'object, quando è impostatoDEBUG_BACKTRACE_PROVIDE_OBJECT.type—->per le chiamate su istanza,::per le chiamate statiche, assente per le funzioni semplici.args— gli argomenti passati alla chiamata (a meno che non venga usatoDEBUG_BACKTRACE_IGNORE_ARGS).
Esempio di base: tracciare lo stack di chiamate
Questo script percorre tre funzioni annidate e stampa una traccia leggibile dalla più profonda:
<?php
function levelThree() {
$trace = debug_backtrace();
foreach ($trace as $i => $frame) {
echo "#$i {$frame['function']}() at line {$frame['line']}\n";
}
}
function levelTwo() { levelThree(); }
function levelOne() { levelTwo(); }
levelOne();Output:
#0 levelThree() at line 8
#1 levelTwo() at line 9
#2 levelOne() at line 10Il frame #0 è dove è stata chiamata debug_backtrace(), e ogni frame successivo è il chiamante superiore. Usa print_r($trace) al posto del ciclo se vuoi vedere tutte le chiavi (file, args, ecc.) in una volta.
Trovare il chiamante
Un uso comune e mirato è scoprire chi ha chiamato la funzione corrente — per il logging o gli avvisi di deprecazione. Passa DEBUG_BACKTRACE_IGNORE_ARGS per mantenere il risultato leggero e 2 come limite, poi leggi il frame all'indice 1 (l'indice 0 è la funzione corrente):
<?php
function logCaller() {
$caller = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1] ?? null;
if ($caller) {
echo "Called by {$caller['function']}() on line {$caller['line']}\n";
}
}
function doWork() {
logCaller();
}
doWork();Output:
Called by doWork() on line 11La guardia ?? null è importante quando logCaller() viene invocata dal livello principale, dove non esiste un frame 1.
Quando usarla
- Logging e diagnostica — aggiungi una traccia a un'entry di log per poter ricostruire come è stato raggiunto uno stato inatteso.
- Avvisi di deprecazione — segnala il chiamante esatto di una funzione che si sta eliminando progressivamente.
- Gestori di errori personalizzati — arricchisci un callback
set_error_handler()con lo stack di chiamate circostante. - Comprensione del flusso del framework — scopri quale middleware o hook ha portato al tuo codice.
Avvertenze
- Prestazioni e memoria. Con le opzioni predefinite ogni frame mantiene i riferimenti a
argseobject, che possono essere pesanti. Nei percorsi critici o quando gli argomenti sono grandi, passaDEBUG_BACKTRACE_IGNORE_ARGS. - Codice in produzione. Tratta
debug_backtrace()come uno strumento di debug. Non lasciare che stampi sull'output in produzione — instradala invece verso un log. - Hai solo bisogno di un output formattato? Usa
debug_print_backtrace(), che stampa direttamente una traccia formattata senza restituire un array. - All'interno di un'eccezione? L'object
Exceptiongenerato porta già la propria traccia tramite$e->getTrace()e$e->getTraceAsString().
Tipi di errore PHP in sintesi
debug_backtrace() è più utile quando si sa già che si è verificato un errore e si desidera il contesto. Gli errori PHP rientrano in alcune categorie principali:
- Errori di analisi (sintassi) — codice non valido che il parser rifiuta prima dell'esecuzione, come un punto e virgola mancante o una parentesi graffa non chiusa. Questi sono fatali.
- Errori logici — il codice viene eseguito ma produce un risultato errato; non c'è alcun messaggio di errore, ed è esattamente quando un backtrace è utile.
- Errori di runtime — sollevati durante l'esecuzione dello script, che vanno da notice e warning non fatali (variabile non definita, include mancante, avvisi di divisione) a errori fatali (chiamare un metodo su un non-object, superare il limite di memoria) che interrompono l'esecuzione.
Per controllare quali di questi visualizzare, imposta il livello con error_reporting(). Durante lo sviluppo, abilita tutto:
<?php
// Report all errors, notices and warnings, and show them
error_reporting(E_ALL);
ini_set('display_errors', '1');graph TD;
A[PHP Error] -->|invalid code| B(Parse / Syntax)
A -->|wrong result| C(Logical)
A -->|while running| D(Runtime)
D --> E(Notice / Warning)
D --> F(Fatal Error)Argomenti correlati
debug_print_backtrace()— stampa un backtrace formattato.error_reporting()— scegli quali errori vengono segnalati.trigger_error()— genera i tuoi errori personalizzati.- PHP Exceptions — gestione strutturata degli errori con
try/catch.