A salvo de errores… o quizá no
StormByte me ha mandado este problema para vosotros, yo esperaré un par de días y después participaré también! 🙂
Problema:
PHP es un lenguage muy dinámico, tanto, que te permite hacer muchas cosas, algunas buenas, algunas documentadas, y otras, no tan buenas y no tan documentadas.
En este caso, hablaremos del gancho (hook) que PHP pone a nuestra disposición para manejar los posibles errores con los que nos podamos encontrar y evitar que salga una advertencia que nos estropee la página.
Se trata de:
mixed set_error_handler ( callable $error_handler [, int $error_types = E_ALL | E_STRICT ] )
Que establece una función de usuario (error_handler) para manejar los errores de un script.
Su uso es muy sencillo, y nos permite estar a salvo de los errores que se nos puedan presentar (junto con error_reporting(0))
Este es el codigo:
<?php error_reporting(0); function erroresBonitos($errno, $errstr, $errfile, $errline) { //Manejar errores aquí, mandar un email, etc } set_error_handler("erroresBonitos", E_ALL); if ($t[0]) { /* no se ejecuta, pero causará un warning que el handler maneja perfectamente sin romper nuestra web */ } //Y finalmente, nuestra web en su bonito HTML, etc echo "Test Mi pagina"; ?>
Con esto, estaríamos a salvo de los errores que se nos puedan presentar, podríamos enviar un email al admin web, guardar el error en la base de datos, e incluso decirle al usuario que nos contacte, pero… ¿estamos seguros del todo?
La respuesta es NO, aún quedan algunos casos para los que no estamos protegidos, y para poder confiar en un handler de errores, tiene que manejar el 100% de los casos.
Con lo que este problema tiene 2 preguntas:
1.- ¿Qué podría ir mal y “saltarse” este handler de errores?
2.- ¿Podríamos protegernos de los casos de la pregunta 1 de alguna forma? Si es así, ¿Cómo podríamos hacerlo?
Esperamos unos días como de costumbre, y si no aparecen respuestas o van muy desencaminadas desvelamos la primera y dejamos algo más de tiempo para la segunda.
1 comentario
Rompo el hielo.
Lo primero es clasificar los tipos de errores que pueden producirse en PHP. Tenemos 4 grandes familias:
1) Errores de ejecución: Típicos warnings, fallos de permisos, divisiones entre 0, etc…
2) Excepciones.
3) Errores fatales: fallos de sintaxis, memoria insuficiente, etc.
4) Errores en drivers o componentes de terceros que no dependen de PHP (como drivers PDO para bases de datos, etc).
Con el código del problema, únicamente estamos controlando los errores de la familia 1. Si lanzamos una excepción nuestro manejador de errores no va a controlarla.
Para las excepciones tenemos una función análoga a set_error_handler que es set_exception_handler.
En la familia 3 de errores fatales, por desgracia, tenemos poco que hacer. La mayoría de errores fatales no permiten ser controlados y la ejecución se aborta sin más. En algunos casos (como en memoria insuficiente) tenemos la posibilidad de escribir un manejador con set_shutdown_function; pero con muchas limitaciones (se ejecuta en un entorno diferente al del script original).
En la cuarta familia dependemos completamente de la implementación de los drivers para que lancen excepciones y errores correctamente. En algunos casos tienen su propio sistema de registro y control de errores por encima del original del lenguaje.
He escrito un código de ejemplo que aúna todo esto con comentarios en español: