Páginas

domingo, 13 de mayo de 2012

Manejo de errores y excepciones PHP

Buenas en esta entrada intentaré explicar un poco el manejo de errores y excepciones con PHP, comenzaremos definiendo un poco que es un error a nivel de programación.
Un error es un problema que pasa en cierta línea de programación a medida que nuestro código es interpretado, un ejemplo muy simple pero bastante recurrente, el no colocar el ";" a final de cada línea de instrucción.

 Una excepción es un problema o algo inesperado que ocurre al intentar interpretar nuestro código. Si vemos los conceptos en teoría son parecidos más no son lo mismo, es importante hacer la aclaración porque habemos quienes la primera vez que vemos el tema creemos que es lo mismo. Llevemos esto a un ejemplo simple

/**
*
* conexion con el servidor
*/
$dns = 'mysql:host=localhost;db=test';
$user = 'user';
$password = 'password';
// si vemos esta línea el interprete de php encuentra un error al no encontrar el final de línea ";"
$connect = new PDO($dns, $user, $password)

ahora si tenemos el mismo código completo pero no están bien los parámetros de la conexión con mysql esto nos lanzará una excepción

/**
*
* conexion con el servidor
*/
$dns = 'mysql:host=localhost;db=test';
$user = 'user';
$password = 'password';
// si vemos esta línea el interprete de php encuentra un error al no encontrar el final de línea ";"
$connect = new PDO($dns, $user, $password);

Ahora como manejarlas?? PHP desde la versión 4 pero mejorada en la versión 5 tiene un soporte para programación orientada a objetos, por lo que podemos explotar estos beneficios. Para manejar las excepciones php tiene varias palabras reservadas las cuales indicaremos a continuación.

 Lo primero que tenemos que conocer es la clase Exception esta nos brinda la posibilidad de manejar todas las excepciones que lance el lenguaje.

 Ahora hablaremos un poco de throw: como bien es traducido a nuestro idioma es lanza, lo usamos para indicarle al interprete que debe lanzar una excepción en caso de que algo no sea lo que necesitamos, un ejemplo simple

function test($a) {
    if(!$a) {
        throw new Exception('Error al comparar a');
    } else  {
       echo $a;
    }
}

En esté código lo que le decimos al interprete de php, es si es falso $a lanza una excepción porque necesitas que esté tenga un valor verdadero.


try/catch Estas dos palabras son importantes e interesantes al momento de trabajar con excepciones, como vemos en su traducción a nuestro lenguaje try es trata, intenta ejecutar el código que esta en este bloque, si existe algún problema o algo inesperado catch o captura la excepción, entonces si continuamos la implementación del código anterior que ya nos lanza una excepción entonces realizaríamos lo siguiente

try {
   test(0);
} catch(Exception $e) {
   $e->getMessage(); 
}

Entonces si pasamos 0 el interprete de php lo toma como falso y este automáticamente lanzara la excepción, como vemos el catch pide como parámetro un objeto del tipo Exception, y cuando captura esta excepción muestra el mensaje.

Hasta ahora todo ha sido fácil y sencillo verdad?? Ahora lo vamos a ver un poco más fácil vamos a trabajar como se debe a partir de PHP5 con objetos, para el manejar las excepciones con objetos no cambia mucho, lo que cambia es que podemos utilizar las ventajas como la herencia para extender de la clase Exception y crear nuestro propio objeto para manejar las excepciones.

Para el caso de los objetos trabajaremos con una sencilla clase

/**
*
* class manager of exception
*/
class TestException extends Exception {}

/**
*
* class for testing this article
*/
class Test 
{
    /**
    *
    * @param Int $number
    */
    public function testInteger($number)
    {   
        if(!is_numeric($number)) {
            throw new TestException('Debe de indicar un numero');
        }
        if(is_int($number)) {
            return true;
        } else {
            return false;
        }
    }
}

Entonces cuando nos toque utilizar este objeto deberíamos realizar lo siguiente

try {
    $test = new Test();
    $test->testInteger(1);
    $test->testInteger('hola');
} catch(TestException $e) {
    echo $e->__toString();
}

si ejecutamos el código nos dara como resultado algo como esto
exception 'TestException' with message 'Debe de indicar un numero' in /var/www/loqueras/Test.php:22 Stack trace: #0 /var/www/loqueras/Test.php(35): Test->testInteger('hola') #1 {main}

Con esto ya sabemos donde y que es lo que esta pasando en nuestro código, como ven no hay error de sintaxis, sino más bien de algo que esperaba la clase.

Tocando un poco otro tema en cuanto al manejo de errores hay un tema importantes al momento de trabajar los mensajes de errores, warning, hay muchos códigos o programadores que utilizan el símbolo "@" o operador de control de error para que el interprete de php no muestre en pantalla el error, esto simplemente es una mala práctica al momento de programar, porque?? porque simplemente ocultar un error no lo corrige, solo lo oculta, es como que te barra la casa y te esconda la tierra bajo la sombra y luego pregunten porque me enferme. Buenos por ahora es todo espero que les sirva este post y ayude a entender un poco mas el manejo de errores y excepciones saludos.