Errores en PHP
Un error, en el ámbito de un lenguaje de programación, es una situación crítica que se produce en nuestro código o programa y que puede llegar, dependiendo del nivel de error, a detener o “romper” el programa.
Creo que es bastante claro y obvio lo que es un error, sin embargo, se pueden producir diferentes tipos de error y, dependiendo del que se produzca, suceda una cosa u otra. Para empezar, debes saber que PHP tiene varios tipos de error:
E_WARNING: Representa una “simple” advertencia. Es un error no fatal y, por tanto, el script/programa sigue ejecutándose.
Por ejemplo, el caso más típico puede ser al incluir un archivo inexistente.
include('archivoquenoexiste.php'); // Genera un E_WARNING echo "Pero el script sigue ejecutándose…";
E_NOTICE: Aviso (menor) sobre que el código puede no funcionar como se espera, pero sin detener la ejecución del script.
Por ejemplo, al usar una variable no definida:
echo $variablequenoexiste; // Genera un E_NOTICE
En ese caso PHP nos avisará de este comportamiento, pero el script seguirá ejecutándose.
E_ERROR: Un error fatal que detiene la ejecución del programa.
Por ejemplo, cuando llamamos a una función que no existe:
funcion_inexistente(); // Genera un E_ERROR echo "Este mensaje no se muestra porque se ha detenido la ejecución del script.";
E_PARSE: Representa un error de sintaxis, es decir, PHP no puede interpretar o leer el código. En otras palabras, es como si no lo reconociera y hace que el script deje de funcionar.
Por ejemplo, cuando olvidamos incluir el famoso punto y coma (;) al final:
echo "Hola, que tal?" // Genera un E_PARSE echo "Esto tampoco se ejecutará.";
Si te preguntas, porque PHP lanza un error fatal (E_ERROR) cuando una función no existe, pero, sin embargo, lanza un E_NOTICE cuando una variable no existe, tranquil@, ahora te explico porque seguro que piensas, ¿no debería lanzar el mismo error?
Pues bien, esto es debido a como PHP evalúa la gravedad de estos dos problemas y como impactan en el programa.
En el primer caso (función inexistente), PHP lanza un E_ERROR, porque se entiende que el programa necesita esa función para continuar. Dado que una función puede contener una parte fundamental del código y necesaria para que el programa/script se ejecute, si intentamos llamar a una función que no existe, PHP no puede saber que código debe de ejecutar, así que, como no puede saber cómo continuar decide lanzar un error fatal deteniendo la ejecución del script.
En el segundo caso (variable inexistente), PHP lanza un E_NOTICE, porque, aunque es un problema, no es lo suficientemente grave como para detener la ejecución del script. PHP trata a la variable como si existiera, pero con un valor null y, por tanto, entiende que el programa puede continuar.
Es cierto que puede hacer que nuestro programa se comporte de manera inesperada, pero el uso de una variable inexistente o no definida, no influye de manera critica con la ejecución del programa y es por eso, que PHP simplemente nos avisará mediante un E_NOTICE sin necesidad de detener el script.
Manejando errores.
Mediante la función error_reporting(), establecemos que errores de PHP serán notificados. Con esta función, puedes controlar qué tipos de errores mostrar o ignorar durante la ejecución del script.
Como hemos visto antes, PHP tiene varios tipos o niveles de error. Así que con error_reporting() podemos especificar cual mostrar. También podemos combinarlos.
Es bastante sencillo:
error_reporting(E_NOTICE); funcionQueNoExiste();
En el ejemplo anterior la función no existe y por tanto eso conlleva un error fatal, sin embargo, al especificar que solo queremos mostrar los tipos de error E_NOTICE, si ejecutamos el código anterior no muestra nada por pantalla, es decir, el error está ahí, pero no lo vemos.
En ese caso lo correcto sería hacer:
error_reporting(E_ERROR); funcionQueNoExiste();
O bien:
error_reporting(E_ALL);
Y mostramos todos los errores.
Aunque también podemos hacer:
// Notificar todos los errores excepto E_NOTICE error_reporting(E_ALL ^ E_NOTICE);
Pero espera, también podemos ocultarlos todos mediante:
error_reporting(0); // Desactiva toda la salida de errores
Evidentemente este último no se recomienda, al menos no en un entorno de desarrollo. En producción podría llegar a ser útil si no queremos que los usuarios vean mensajes de error no deseados.
Por otro lado tenemos la función set_error_handler(), que nos permite manejar y personalizar los errores. Esta función nos permite personalizar la respuesta a los diferentes tipos de error.
Por ejemplo, si tenemos una variable que no existe como la siguiente:
echo $variable_inexistente; // No definida, genera un E_NOTICE
Al ejecutar el código nos muestra algo así:
Warning: Undefined variable $variable_inexistente in C:\laragon\www\PHP\temas blog\ejemplos\errores-y-excepciones\errores.php on line 6
Pues bien, mediante la función set_error_handler(), podemos manejar ese error (y otros) y que se muestren de manera más personalizada.
function manejadorErrores($errno, $errstr, $errfile, $errline) { echo "Error [$errno]: $errstr en $errfile línea $errline"; // a partir de aqui podemos hacer otras cosas como enviar el error por email, etc. } // Asignamos nuestro manejador de errores a la función set_error_handler set_error_handler("manejadorErrores"); echo $variable_inexistente; // No definida, genera un E_NOTICE
Ahora, si ejecutamos el código nos muestra:
Error [2]: Undefined variable $variable_inexistente en C:\laragon\www\PHP\temas blog\ejemplos\errores-y-excepciones\errores.php línea 13
Como ves, esto puede ser útil porque podemos decidir qué hacer cuando ocurre un error. Por ejemplo, podemos registrar los errores en un archivo (.log), enviar un correo para notificar al equipo de desarrollo que ha ocurrido un error y otras tantas cosas.
Como ves, la diferencia entre error_reporting() y set_error_handler() es que, con el primero controlamos que errores se mostrarán y con el segundo, definimos un manejador de errores que nos permite capturar y manejar estos de manera personalizada.
display_errors y error_reporting()
También veo importante resaltar la diferencia entre estas dos funciones.
Con error_reporting() definimos que tipos de errores son notificados, es decir, cuales se muestran y cuáles no. Pero es con display_errors, que definimos si los errores se muestran por pantalla o no.
Veamos algunos ejemplos.
Para empezar, display_errors es una directiva de configuración de PHP que controla si los errores se muestran o no en el navegador del usuario. Esto es útil durante el desarrollo, ya que nos permite ver los errores en pantalla. Sin embargo, si nos encontramos en producción, es mejor desactivarlo, ya que mostrar errores al usuario final puede revelar información sensible.
Podemos modificar directamente el archivo php.ini y añadir uno de los valores siguientes:
1 (On): Muestra los errores en el navegador.
0 (Off): Oculta los errores.
Podemos modificarlo y dejarlo así:
display_errors = On
O bien en tiempo de ejecución usando ini_set():
ini_set('display_errors', '1'); // Habilita la visualización de errores
Repito, con display_errors controlamos si los errores se muestran o no en el navegador, pero no define qué tipos de errores deben mostrarse. Para eso debes usar error_reporting().
También se pueden combinar ambos. Uno para un entorno de desarrollo y otro para producción.
Por ejemplo, en desarrollo lo lógico es mostrar los errores (display_errors activado) y mostrar todos los tipos de error que se pueden producir.
ini_set('display_errors', '1'); // Habilita la visualización de errores error_reporting(E_ALL); // Reporta todos los tipos de errores
No es igual para un entorno de producción, donde se recomienda desactivar la visualización de errores para evitar mostrar información sensible:
ini_set('display_errors', '0'); // Desactiva la visualización de errores error_reporting(0); // No muestra ningún error
Y hasta aquí una pequeña introducción al tema de los errores. En un próximo artículo, llamémosle… “parte 2”, hablare sobre las excepciones, que, para introducirnos un poco, decir que los errores y las excepciones, ya sean en PHP o en cualquier otro lenguaje, no son exactamente lo mismo. No nos referimos a lo mismo. Y aunque ambos representan un problema en nuestro programa, tienen algunas diferencias.
Una excepción es una situación excepcional prevista, o, en otras palabras, es un problema previsible y controlable mientras que, un error, es un problema crítico que puede detener el flujo normal de nuestro programa… En fin, como acabo de decir, ya hablaremos en una segunda parte 😉