2009-08-09 9 views
41

Imagínese que tengo la siguiente situación:¿Obtiene la línea de código y el archivo que está ejecutando la función actual en PHP?

file1.php

<?php 
include("Function.php"); 
log("test"); 
?> 

function.php

<?php 
function log($msg) 
{ 
    echo ""; 
} 
?> 

quiero cambiar la función de registro para que se produciría lo siguiente:

prueba (archivo: File1.php, número de línea: 3)

Entonces, ¿alguna forma de obtener el nombre del archivo y el número de línea del código que ejecutó la función actual en PHP?

EDITAR para el uso de backlog comentarios de uso: Cuando uso el backlog en mi modo orientado a objetos de programación tengo la siguiente situación.

Index.php

<?php 
include("Logger.static.php"); 
include("TestClass.class.php"); 
new TestClass(); 
?> 

TestClass.class.php

<?php 
class TestClass 
{ 
    function __construct() 
    { 
    Logger::log("this is a test log message"); 
    } 
} 
?> 

Logger.static.php

<?php 
class Logger 
{ 
    static public function log($msg) 
    { 
    $bt = debug_backtrace(); 
    $caller = array_shift($bt); 
    echo $caller['file']; 
    echo $caller['line']; 
    } 
} 
?> 

En este ejemplo se volverá como archivo "Index.php" y como la línea número 4, aquí es donde se inicia la clase. Sin embargo, se supone que devuelve el archivo TestClass.class.php y el número de línea 6. ¿Alguna idea de cómo solucionar esto?

Respuesta

73

Puede usar debug_backtrace().

http://us3.php.net/manual/en/function.debug-backtrace.php

Por lo tanto, en su función de registro, que sería capaz de recuperar el número de nombre de archivo y la línea de la que se llama la función de registro.

Estoy utilizando este enfoque en mis clases de registro y se ha reducido significativamente la cantidad de código necesario para obtener datos de registro significativos. Otro beneficio sería la legibilidad. Las constantes mágicas tienden a ponerse bastante feas cuando se mezclan con cadenas.

Aquí está un ejemplo rápido:

function log($msg) 
{ 
    $bt = debug_backtrace(); 
    $caller = array_shift($bt); 

    // echo $caller['file']; 
    // echo $caller['line']; 

    // do your logging stuff here.  
} 
+1

En realidad, hay un problema. Estoy codificando de forma orientada a objetos y devuelve la línea y el script que llama al objeto en el que se llama a la función. En cambio, debería darme el nombre de la clase incluida y la línea dentro de ese archivo de clase. ¿Alguna idea? – Tom

+0

Debe ser más específico aquí. ¿Me puede mostrar lo que está recibiendo y lo que está esperando en su lugar? –

+0

Hola Lior Cohen, ¿podría revisar mi publicación original editada? Expliqué todo en detalle allí. ¡Gracias! – Tom

21

debug_backtrace() se puede utilizar para rastrear a través de la pila de llamadas. Sin embargo, puede ser lento, así que tenga cuidado con él si está realizando una gran cantidad de registros.

Si está usando PHP 5.3, se podría aprovechar late static binding y tener un método de la clase base del log() y sus clases hijas podría llamar, pero todavía mantienen referencias estáticas a __FILE__ y __LINE__.

Una última opción sería simplemente pasar __FILE__ y __LINE__ como parámetros cuando llame a la función log().

+0

'__FILE__' y' __LINE__' pueden ser mucho más eficientes, aunque agrega desorden de código. Por cierto, tal vez la debida depuración podría reemplazar el registro de archivos/líneas cuando surja la necesidad. – christopheml

+0

'debug_backtrace()' ralentiza en 2 veces desde '__LINE__', pero esto permite 100 llamadas en 1 ms para una computadora promedio o 1000 llamadas en 1 ms para un servidor potente. Entonces no es tan lento como puede ser. – Enyby

1

Ésta es una vieja pregunta, pero viendo que mi solución no está aquí, voy a proporcionar para la posteridad

 try{ 
     throw new Exception(); 
    }catch (Exception $e){ 
     $trace = $e->getTrace(); 
    } 

    $length = 0; 

    foreach ($trace as $t){ 
     if($t['file'] != __FILE__){ 
      break; 
     } 
     ++$length; 
    } 
    return array_slice($trace, ($length - count($trace))); 

Usted puede lanzar/catch para obtener un seguimiento limpio de la pila, luego debe buscar la primera línea que contiene este archivo (generalmente, de ahí es donde se llama), también puede usar el índice de la huella, si la conoce, o la función.

El seguimiento de pila de excepción es prácticamente el mismo que en debug_backtrace(true).

Cuestiones relacionadas