Considere siguiente código:
<?
class BtTest
{
public function getTheItem()
{
var_dump(debug_backtrace(false));
$bt = debug_backtrace(false);
return $bt[1];
}
public function __call($methodName, $methodArgs)
{
return $this->getTheItem();
}
}
$o = new BtTest();
$bti = $o->test();
assert('array_key_exists("function", $bti)');
assert('array_key_exists("line", $bti)');
assert('array_key_exists("file", $bti)');
La ejecución del ejemplo anterior genera siguiente resultado:
array(3) {
[0]=>
array(6) {
["file"]=>
string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php"
["line"]=>
int(13)
["function"]=>
string(10) "getTheItem"
["class"]=>
string(6) "BtTest"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
[1]=>
array(4) {
["function"]=>
string(6) "__call"
["class"]=>
string(6) "BtTest"
["type"]=>
string(2) "->"
["args"]=>
array(2) {
[0]=>
&string(4) "test"
[1]=>
&array(0) {
}
}
}
[2]=>
array(6) {
["file"]=>
string(53) "/somewhere/in/the/filesystem/tests/bt-test-so.php"
["line"]=>
int(18)
["function"]=>
string(4) "test"
["class"]=>
string(6) "BtTest"
["type"]=>
string(2) "->"
["args"]=>
array(0) {
}
}
}
PHP Warning: assert(): Assertion "array_key_exists("line", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 21
PHP Warning: assert(): Assertion "array_key_exists("file", $bti)" failed in /somewhere/in/the/filesystem/tests/bt-test-so.php on line 22
El primer elemento traza (índice 0) dice indirectamente (a través de los line
y file
artículos) que se llamó al método getTheItem
desde el método __call
.
El segundo elemento traza (índice 1) dice que el método __call
fue llamado desde algún lugar (falta line
y file
artículos).
El tercer elemento de seguimiento (índice 2) dice que se llamó al método test
desde el alcance global del script.
El lugar de la llamada al método __call
es probablemente en algún código de resolución de método en algún lugar del código del intérprete php. Hay dos posibilidades de arreglarlo. O el segundo elemento debe referir el archivo de código fuente y la línea del intérprete o el segundo y el tercer elemento de rastreo deben fusionarse en uno. Yo personalmente preferiría la segunda solución ya que las partes internas del intérprete no son interesantes para mí (así es como parecen hacerlo en el rastreo de Python), sin embargo, entiendo que a veces la primera solución proporciona un rastro más explícito (especialmente cuando es una devolución de llamada que es llamado desde el interior).
Por lo tanto, parece que el desarrollador (es) responsable (o al menos mantener) el código de la función debug_backtrace
no lo percibe como un error o tal vez no tiene una manera fácil de solucionarlo. Sería correcto rellenar los artículos line
y file
con algunos valores de marcador de posición (por ejemplo, <unknown-file>
y 0
o incluso nulos) y enfatizarlo en la documentación. A menos que alguien los convenza con éxito de hacerlo, solo tiene que manejar el caso especial en su código.
Escribí anteriormente solo para compartir mi comprensión del comportamiento extraño de la función.Si alguien tiene la voluntad de luchar por un mundo un poco mejor, aquí están los enlaces a algunos informes de errores relacionados:
El informe más antiguo es de 2003, por lo que no debería cuenta con una solución rápida :)
Interesante. Puede publicar un ejemplo? – deceze
¿Está quizás dentro de una excepción, cierre, código evacuado, función tick, manejador de errores (básicamente, cualquier código que opera fuera de la pila de ejecución normal)? Aparte de eso, no puedo ver por qué no obtendrías los números de línea (sin un ejemplo al menos) ... – ircmaxell
@deceze - El código es demasiado complejo para poner un ejemplo. Ojalá pudiera hacerlo, pero tomaría horas o más para identificar algo lo suficientemente simple como para publicar y no es un gran problema para mí pasar todo ese tiempo. – MikeSchinkel