2008-12-06 8 views
22

¿Existe alguna razón convincente para no usar debug_backtrace con el único propósito de determinar la clase, el nombre y la lista de parámetros del método de llamada? No para fines de depuración. Tiene la palabra "debug" en el nombre de la función, lo que me hace sentir un poco sucio de usarlo de esta manera, pero se ajusta a la factura de lo que necesitaba hacer (una sola función que se puede llamar desde muchos lugares y necesita llamar al método de llamada de otro sistema). Funciona, pero ¿sigue siendo una mala idea? Si es así, ¿por qué?PHP debug_backtrace en el código de producción para obtener información sobre el método de llamada?

+0

debug_backtrace tiene un error: leer http://stackoverflow.com/q/4581969/632951 – Pacerier

Respuesta

13

Se siente un poco sucio, pero como ha sido bien documentado, opinado y golpeado hasta la muerte en otro lugar, PHP no es un sistema diseñado para la elegancia.

Una razón muy intrincada no para usar debug_backtrace para la lógica de la aplicación es posible que un futuro desarrollador que trabaje en PHP pueda decidir "es solo una función de depuración, el rendimiento no importa".

Si le interesa una forma "mejor" de hacerlo, probablemente podría usar PHP's magic constants para pasar el método de llamada y el nombre de clase, y luego usar un objeto ReflectionMethod para extraer cualquier otra información que necesite.

Pongo mejor entre comillas porque, aunque esto sería más limpio y más correcto, la sobrecarga de instanciar un objeto Reflection puede ser mayor que usando la función debug_backtrace.

+0

Sí, no sabía acerca de __CLASS__ o __FUNCTION__ en ese momento. O el objeto Reflection. Creo que si tuviera que hacerlo de nuevo, lo haría de esa manera en su lugar. – Sydius

+0

Otra cosa a tener en cuenta es la frecuencia con la que lo necesita: el mantenimiento de información similar en el código PHP agregaría ciclos significativos a cada solicitud, por lo que un 'debug_stacktrace' ocasional sería sin duda preferible. En general, sin embargo, estoy de acuerdo con Konrad: aparte de las necesidades de depuración/registro/inusuales, el diseño no debería ser necesario. –

15

¿Existe alguna razón convincente para no usar debug_backtrace con el único propósito de determinar la clase, el nombre y la lista de parámetros del método de llamada?

Sí. El punto es que, en general, es un signo de mal diseño si su código requiere un acoplamiento tan ajustado que el destinatario debe tener esta información sobre su interlocutor. Por lo tanto, si siente la necesidad de utilizar esta información, probablemente deba reconsiderar su diseño.

Dicho sin rodeos, el destinatario no debería necesitar esta información para realizar su tarea. Las excepciones, por supuesto, giran en torno a la depuración, el registro y, en general, otros tipos de introspección de código (pero incluso allí, ten cuidado).

+0

La tarea del destinatario es llamar al mismo método que lo llamó en una computadora diferente. Es para evitar tener una función API diferente para cada fuente posible, lo que reduce considerablemente la cantidad de código en el sistema. ¿Sigue siendo malo? – Sydius

+0

Honestamente tengo que decir que no sé. No veo ninguna manera de manejar esto de manera diferente, por lo que este podría ser un caso apropiado para dicho uso. –

+0

pero está bien usarlo en el manejador de errores, ¿verdad? – Mawg

4

debug_backtrace es una de las funciones de manejo de errores de PHP. El manual alienta a los usuarios a definir sus propias reglas de manejo de errores, así como a modificar la forma en que se pueden registrar los errores. Esto le permite cambiar y mejorar los informes de errores para satisfacer sus necesidades. Esto también implica que el rendimiento alcanzado por el uso de estas funciones es insignificante.

Creo que lo que estás haciendo está bien.

3

que ha dicho en un comentario

La tarea del destinatario de la llamada es llamar al mismo método que la llamó en un equipo diferente. Es para evitar tener una función API diferente para cada fuente posible, lo que reduce considerablemente la cantidad de código en el sistema.¿Sigue siendo mala

Así que quieres hacer lo siguiente:

Suponiendo, por supuesto, que use las solicitudes HTTP para activar la llamada remota.

Esta es una configuración un tanto extraña. Si está creando el sistema desde cero, le sugiero que trate de evitarlo. Si lo calzas con un sistema heredado, entonces supongo que lo entiendo.

Sugiero que siempre seas más explícito cuando puedas. El uso de la introspección de la pila mágica puede ahorrarle un poco de codificación, pero para otro desarrollador su código será completamente desconcertante. Si está sugiriendo que pase la clase y el nombre de la función a la función que previamente estaba haciendo la reflexión. Entonces no hay ambigüedad sobre lo que está sucediendo.

+0

No sabía acerca de __CLASS__ y __FUNCTION__ cuando lo escribí por primera vez, o de lo contrario probablemente lo habría hecho. Quería algo fácil de copiar/pegar (y constante). Realmente me gustaría que PHP tuviera macros (tan malos como pueden ser abusados). – Sydius

0

Estoy pensando en usar el debug_backtrace de depurar las declaraciones de mysql. Es un infierno mucho más fácil de identificar consultas erróneas o lentos cuando se tiene un encabezado como esto al comienzo de cada consulta dentro de los registros de base de datos:

/*Called from /var/www/micimacko.php at line 28*/ SELECT count(*) FROM rofibeka; 

queda la cuestión. ¿Qué hay de rendimiento/fiabilidad.

+1

La función trigger_error() hace exactamente lo que describió, además guarda el error en el registro de errores de Apache. Utilizo trigger_error (mysql_error()) para guardar todas las fallas y registrarlas o mostrarlas en la pantalla (dependiendo de si estoy en un servidor de producción o desarrollo). –

2

La respuesta correcta es que es totalmente OK. Alan señala la falta de elegancia de PHP, por lo que no voy a reiterar sus puntos. La razón para (no tener miedo a) usar debug_backtrace en el código de tiempo de ejecución es porque PHP es principalmente un lenguaje libre de contexto. Cada función no sabe ni puede conocer la "intención" del que llama sin utilizar los nombres de las funciones mágicas (por ejemplo, en una clase, por ejemplo, __toString()) con el casting. Consideremos el caso en el que tiene una clase, en la que (en un método), desea proporcionar acceso a las propiedades de la clase llamante (externa). Es realmente desordenado y propenso a pasar errores ($ this) a través de la función API. (Especialmente cuando quiere array_map o call_user_func_array.)

p.

<? 
class a { 
public $v = 'xyz'; 
function __construct($x,$y) 
{ 
    $b = new b(); 
} 
} 
class b { 
function __construct() 
{ 
    $start = microtime(); 
    $x = debug_backtrace(); 
    $end = microtime(); 
    echo ($end-$start) . "\n"; 
    print_r($x); 
    $obj = $x[1]['object']; 
    print_r($obj); 
} 
} 
$a = new a(1,2); 
?> 

La debug_backtrace le dará acceso al contexto de la clase a en la __construcción de b. Ahora puede pasar algunas variables de estado de la clase actual sin pasar $ this alrededor o tratando de adivinarlo de nombres de clase o bloquearlo poniéndolo en globales.

Para aquellos que estén interesados ​​en el tiempo, la microtime fue 2.7E-5. Suficientemente rapido. Simplemente no lo pongas por un tiempo (1).

Cuestiones relacionadas