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.


Si te gusta esta entrada... compártela! 😉
Tweet about this on TwitterShare on Facebook0Share on Google+0Share on Tumblr0Pin on Pinterest0Share on LinkedIn0Share on Reddit0

1 comentario

  1. LaNsHoR

    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:

    <?php
    //Cancelamos todos los manejadores de errores
    //por defecto de PHP
    ini_set("display_errors", "off");
    //Activamos los triggers para todos los tipos
    //de errores
    error_reporting(E_ALL);
    
    //Manejador de errores
    function my_funny_error_handler($error_code,
      $description, $file, $line, $context=null)
    {
       // *** your magic code here
    }
    
    //Manejador de excepciones
    function my_funny_exception_handler(Exception $ex)
    {
       // *** your magic code here
       die(); //Todas las excepciones no recogidas
       //deben abortar el programa
    }
    
    //Manejador de errores fatales
    //(por ejemplo: fallos en reserva de memoria)
    function my_funny_fatal_error_handler()
    {
       $error=error_get_last();
       // *** your magic code here
    }
    
    register_shutdown_function("my_funny_error_handler");
    set_error_handler("my_funny_error_handler");
    set_exception_handler("my_funny_exception_handler");
    
    echo "Hola Mundo!";
    ?>
    

Responder a LaNsHoR Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Límite de tiempo se agote. Por favor, recargar el CAPTCHA por favor.