Inicio ¿Sidebar? RSS

Gestión de Errores en PHP

Ya casi dos años sin Internet en casa me ha hecho controlar un poco esa horrible costumbre de chatear casi todo el día y cambiarla por programar alguna tontería (Re-Inventar la rueda obviamente puff! :P ).

Esta vez estuve pensando como solucionar el problema al que me enfrento cuando estoy a cargo de varios proyectos al mismo tiempo, y me veo en la situación de trabajar casi a ciegas, y sin revisar la entrada de datos detenidamente, o sencillamente si funciona o no… y todo debido a la presión del trabajo.

La idea es encontrar todos los errores de forma rápida, sencilla, y sin tener que navegar o testear mis aplicaciones Web una y otra vez cada que hago modificaciones o nuevas implementaciones.

Se me ocurrió que existiera la posibilidad de anular el gestor de errores de PHP, y crear un propio que me permitiera guardar los errores en un archivo, y luego de cierto tiempo revisarlo y que ahí estuviera cacheados todos los errores ocurridos… Y bueno, después de leer un rato la documentación de PHP terminé configurando el servidor a mi medida desde el php.ini, pero,… pensé ¿Se podrá crear una función aplicable a cada sistema en particular sin revolver todos los errores de todos los sistemas en el mismo log de errores? Bueno, la respuesta fue si, y no solo eso, me encontré con que las posibilidades son mayores: Puedo de cierta forma cachear el contexto en el que el error ha ocurrido, por ejemplo guardar todas las variables en GET y POST. Esto me ayudaría a darme cuenta de si alguien mal intencionado insertó alguna consulta que me halla causado el error (la IP, los datos de sesión de algún usuario, etc…).

Y bueno, he aquí los resultados:

  1. define('error_file','error_log.html');
  2. function error_handler($num_err, $cadena_err, $archivo_err="", $linea_err="", $contexto_err=""){
  3.         /*
  4.             (PHP 4 >= 4.0.1, PHP 5)
  5.             $num_err - nivel de error generado, como un entero.
  6.             $cadena_err - mensaje de error, como una cadena.
  7.            
  8.             PHP >= 4.0.2    
  9.             $archivo_err - nombre del archivo en el que se generó el error, como una cadena.
  10.             $linea_err - número de línea en la que se generó el error, como un entero.
  11.             $contexto_err - matriz que apunta a la tabla activa de símbolos en el punto en el que ocurrio el error.
  12.         */
  13.         $errores = array (
  14.             E_ERROR              => 'E_ERROR',
  15.             E_WARNING            => 'E_WARNING',
  16.             E_PARSE              => 'E_PARSE',
  17.             E_NOTICE             => 'E_NOTICE',
  18.             E_CORE_ERROR         => 'E_CORE_ERROR',
  19.             E_CORE_WARNING       => 'E_CORE_WARNING',
  20.             E_COMPILE_ERROR      => 'E_COMPILE_ERROR',
  21.             E_COMPILE_WARNING    => 'E_COMPILE_WARNING',
  22.             E_USER_ERROR         => 'E_USER_ERROR',
  23.             E_USER_WARNING       => 'E_USER_WARNING',
  24.             E_USER_NOTICE        => 'E_USER_NOTICE'
  25.         );
  26.        
  27.         if(defined('E_STRICT'))
  28.             $errores[E_STRICT] = 'E_STRICT';// PHP > 5
  29.         if(defined('E_RECOVERABLE_ERROR'))
  30.             $errores[E_RECOVERABLE_ERRROR] = 'E_RECOVERABLE_ERRROR';// PHP > 5.2
  31.        
  32.         ob_start();
  33.         echo "<strong>{$errores[$num_err]}</strong>: $cadena_err in <strong>$archivo_err</strong> on line <strong>$linea_err</strong>";
  34.         //echo date(" Y-m-d H:i:s (T)");
  35.        
  36.         //PHP >= 4.0.2, para versiones anteriores habría que analizar si _GET o _POST están definidos y tienen valores
  37.         /*Si el contexto en el que ocurrieron los errores venía acompañado de variables
  38.         por el método _POST, estas se mostrarán en el error.*/
  39.             if(isset($contexto_err['_POST']) and count($contexto_err['_POST'])>0){
  40.                     echo " _POST: ";
  41.                     echo"<pre>";        
  42.                     print_r($contexto_err['_POST']);
  43.                     echo"</pre>";
  44.                 }
  45.         /* Lo mismo para _GET */
  46.             if(isset($contexto_err['_GET']) and count($contexto_err['_GET'])>0){
  47.                     echo"<pre>";
  48.                     echo"_GET:";
  49.                     print_r($contexto_err['_GET']);
  50.                     echo"</pre>";
  51.                 }
  52.         echo "<br />n";
  53.         error_log(ob_get_clean(), 3, error_file);
  54.     }

Para utilizarla, solo hay que incluir la función en la aplicación, y decirle a php que la convierta en el manejador de errores de la siguiente forma:

  1. set_error_handler("error_handler");

donde error_handler corresponde al nombre de la función que recibirá todos los datos correspondientes a los errores, para que hagamos lo que queramos con ellos.

Y para las consultas SQL no encontré una forma de hacerlo similar a la anterior, pero si se me ocurrió hacerlo algo así como con el clásico or die(mysql_error) de la siguiente forma:

  1. define('error_file','error_log.html');
  2.     function guardar_error($linea){
  3.         $fh = fopen(error_file,"a");
  4.         fwrite($fh,"<strong>Mysql_error ".mysql_errno()."</strong>: ".mysql_error()." in <strong>{$_SERVER['SCRIPT_FILENAME']}</strong> on line <strong>$linea</strong><br />n");
  5.     }
  6. Mysql_query($sqlStr) or die(guardar_error(__LINE__));

Y de igual forma, ir controlando un poco los errores.

No tengo idea de si he re-inventado la rueda, o exista una solución parecida a la mia y mejor aún, pero… Me sacó del apuro en el trabajo :D

Cualquier duda, comentario, sugerencia, desacuerdo o mentada es bien recibida. ;-)

4 comentarios en Gestión de Errores en PHP

j0an

gracias! ya lo tengo a prueba a ver como funciona y si me termina sirviendo (administro cerca de 10 sitios, y me viene barbaro)

:)

Victor

:-D Suerte con eso, cualquier detalle, por aquí puedes comentarle :-)

Manejo errores con php

[...] Gestión de Errores en PHP [...]

tttony

hola estaba buscando algo similar a esto pero veo no solo se guarda el error en el caso de mysql y no se podria mostrar algo al usuario como: ha ocurrido un error inesperado....

y bueno tambien para el otro caso si algun usuario como siempre pasa cambia un valor GET o POST deberia de mostrar un mensaje de error personalizado...

saludos y espero respuestas...

Deja un comentario

¿Cuanto es 2 + 3? =

Suscribirse a los comentarios.