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

Suscribirse a los comentarios.