PHP Manejo de excepciones
Las excepciones se utilizan para cambiar el flujo normal de un script cuando ocurre un error especificado.
¿Qué es una excepción?
PHP 5 proporciona un nuevo método de manejo de errores orientado a objetos.
El manejo de excepciones se utiliza para cambiar el flujo normal del script cuando ocurre una situación de error (excepción) especificada. Esta situación se llama excepción.
Cuando se desencadena una excepción, normalmente ocurre lo siguiente:
- Se guarda el estado actual del código
- La ejecución del código se cambia a una función de manejador de excepciones predefinida (personalizada)
- Según la situación, el manejador puede reiniciar la ejecución del código desde el estado guardado, terminar la ejecución del script, o continuar la ejecución del script desde otra ubicación en el código.
Mostraremos diferentes métodos de manejo de errores:
- Uso básico de excepciones
- Crear un manejador de excepciones personalizado
- Múltiples excepciones
- Relanzar excepciones
- Establecer un manejador de excepciones de nivel superior
Nota:Las excepciones solo deben usarse en condiciones de error, y no deben usarse para saltar a otra ubicación del código en un punto específico.
Uso básico de excepciones
Cuando se lanza una excepción, el código posterior no continúa ejecutándose; PHP intenta buscar un bloque "catch" coincidente.
Si la excepción no se captura y no se utiliza set_exception_handler() para manejarla adecuadamente, entonces ocurrirá un error grave (error fatal) y se mostrará un mensaje de error "Uncaught Exception" (excepción no capturada).
Intentemos lanzar una excepción sin capturarla:
El código anterior producirá un error similar a este:
Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below' in /www/ejemplo/test/test.php:7 Stack trace: #0 /www/ejemplo/test/test.php(13): checkNum(2) #1 {main} thrown in /www/ejemplo/test/test.php on line 7
Try, throw y catch
Para evitar el error que aparece en el ejemplo anterior, necesitamos crear el código adecuado para manejar las excepciones.
El código adecuado para el manejo de excepciones debe incluir:
- Try: la función que usa excepciones debe estar dentro de un bloque "try". Si no se desencadena una excepción, el código continuará ejecutándose con normalidad. Pero si se desencadena una excepción, se lanzará una excepción.
- Throw: aquí se especifica cómo desencadenar la excepción. Cada "throw" debe corresponder al menos a un "catch".
- Catch: el bloque "catch" captura la excepción y crea un objeto que contiene la información de la excepción.
Vamos a desencadenar una excepción:
El código anterior producirá un error similar a este:
Message: 变量值必须小于等于 1
Explicación del ejemplo:
El código anterior lanzó una excepción y la capturó:
- Se crea la función checkNum(). Esta comprueba si el número es mayor que 1. Si es así, lanza una excepción.
- Se llama a la función checkNum() dentro del bloque "try".
- Se lanza la excepción en la función checkNum().
- El bloque "catch" recibe la excepción y crea un objeto ($e) que contiene la información de la excepción.
- Al llamar a $e->getMessage() desde este objeto exception, se muestra el mensaje de error de la excepción.
Sin embargo, para seguir el principio de "cada throw debe corresponder a un catch", se puede establecer un manejador de excepciones de nivel superior para manejar los errores omitidos.
Crear una clase Exception personalizada
Crear un manejador de excepciones personalizado es muy simple. Simplemente creamos una clase especializada cuyas funciones pueden llamarse cuando ocurre una excepción en PHP. Esta clase debe ser una extensión de la clase exception.
Esta clase personalizada customException hereda todas las propiedades de la clase exception de PHP, y puede agregarle funciones personalizadas.
Comenzamos a crear la clase customException:
Esta nueva clase es una copia de la antigua clase exception, más la función errorMessage(). Precisamente porque es una copia de la clase antigua, hereda las propiedades y métodos de la clase antigua; podemos usar métodos de la clase exception, como getLine(), getFile() y getMessage().
Explicación del ejemplo:
El código anterior lanzó una excepción y la capturó mediante una clase exception personalizada:
- La clase customException() se creó como una extensión de la antigua clase exception. De esta manera hereda todas las propiedades y métodos de la antigua clase exception.
- Se crea la función errorMessage(). Si la dirección de e-mail no es válida, esta función devuelve un mensaje de error.
- Se asigna a la variable $email una cadena de dirección de e-mail no válida.
- Se ejecuta el bloque "try"; como la dirección de e-mail no es válida, se lanza una excepción.
- El bloque "catch" captura la excepción y muestra el mensaje de error.
Múltiples excepciones
Se pueden usar múltiples excepciones para un script, para detectar varias situaciones.
Se pueden usar múltiples bloques if..else, o un bloque switch, o anidar múltiples excepciones. Estas excepciones pueden usar diferentes clases exception y devolver diferentes mensajes de error:
Explicación del ejemplo:
El código anterior prueba dos condiciones; si alguna de ellas no se cumple, lanza una excepción:
- La clase customException() se creó como una extensión de la antigua clase exception. Así hereda todas las propiedades y métodos de la antigua clase exception.
- Se crea la función errorMessage(). Si la dirección de e-mail no es válida, la función devuelve un mensaje de error.
- Se asigna a la variable $email una cadena que es una dirección de e-mail válida, pero que contiene la cadena "example".
- Se ejecuta el bloque "try"; en la primera condición no se lanza una excepción.
- Debido a que el e-mail contiene la cadena "example", la segunda condición desencadena una excepción.
- El bloque "catch" captura la excepción y muestra el mensaje de error adecuado.
Si la clase customException lanza una excepción, pero no se captura customException, solo se captura la excepción base, entonces la excepción se maneja allí.
Relanzar excepciones
A veces, cuando se lanza una excepción, es posible que desee manejarla de una manera diferente a la estándar. Puede volver a lanzar la excepción dentro de un bloque "catch".
El script debe ocultar los errores del sistema al usuario. Para el programador, los errores del sistema pueden ser importantes, pero al usuario no le interesan. Para facilitar su uso al usuario, puede volver a lanzar una excepción con un mensaje más amigable para el usuario:
Explicación del ejemplo:
El código anterior comprueba si la dirección de correo contiene la cadena "example". Si la contiene, vuelve a lanzar la excepción:
- La clase customException() se creó como una extensión de la antigua clase exception. De esta manera, hereda todas las propiedades y métodos de la antigua clase exception.
- Crear la función errorMessage(). Si la dirección de correo electrónico no es válida, la función devuelve un mensaje de error.
- Establecer la variable $email a una cadena que sea una dirección de correo electrónico válida, pero que contenga la cadena "example".
- El bloque de código "try" contiene otro bloque "try", de modo que se puede volver a lanzar una excepción.
- Como el correo electrónico contiene la cadena "example", se dispara la excepción.
- El bloque "catch" captura la excepción y vuelve a lanzar "customException".
- Se captura "customException" y se muestra un mensaje de error.
Si la excepción no se captura en el bloque "try" actual, se buscará un bloque catch en un nivel superior.
Establecer un manejador de excepciones de nivel superior
La función set_exception_handler() puede establecer una función definida por el usuario que maneje todas las excepciones no capturadas.
La salida del código anterior es la siguiente:
Exception: Uncaught Exception occurred
En el código anterior, no existe un bloque "catch", sino que se activa el manejador de excepciones de nivel superior. Se debe usar esta función para capturar todas las excepciones no capturadas.
Reglas de las excepciones
- El código que requiere manejo de excepciones debe colocarse dentro de un bloque try, para poder capturar posibles excepciones.
- Cada bloque try o throw debe tener al menos un bloque catch correspondiente.
- El uso de múltiples bloques catch permite capturar diferentes tipos de excepciones.
- Se puede lanzar (volver a lanzar) una excepción dentro de un bloque catch que se encuentre en un bloque try.
En resumen: si se lanza una excepción, debe capturarse.
Otras extensiones