Excepciones¶
La gestión de excepciones forma parte desde PHP 5. Su funcionamiento es similar a Java, haciendo uso de un bloque try / catch / finally
.
Si detectamos una situación anómala y queremos lanzar una excepción, deberemos realizar throw new Exception
(adjuntando el mensaje que lo ha provocado).
<?php
try {
if ($divisor == 0) {
throw new Exception("División por cero.");
}
$resultado = $dividendo / $divisor;
} catch (Exception $e) {
echo "Se ha producido el siguiente error: ".$e->getMessage();
}
La clase Exception
es la clase padre de todas las excepciones. Su constructor recibe mensaje[,codigoError][,excepcionPrevia]
.
A partir de un objeto Exception
, podemos acceder a los métodos getMessage()
y getCode()
para obtener el mensaje y el código de error de la excepción capturada.
El propio lenguaje ofrece un conjunto de excepciones ya definidas, las cuales podemos capturar (y lanzar desde PHP 7). Se recomienda su consulta en la documentación oficial.
Creando excepciones¶
Para crear una excepción, la forma más corta es crear una clase que únicamente herede de Exception
.
``` php
<?php
class HolaExcepcion extends Exception {}
Si queremos, y es recomendable dependiendo de los requisitos, podemos sobrecargar los métodos mágicos, por ejemplo, sobrecargando el constructor y llamando al constructor del padre, o rescribir el método __toString
para cambiar su mensaje:
<?php
class MiExcepcion extends Exception {
public function __construct($msj, $codigo = 0, Exception $previa = null) {
// código propio
parent::__construct($msj, $codigo, $previa);
}
public function __toString() {
return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
}
public function miFuncion() {
echo "Una función personalizada para este tipo de excepción\n";
}
}
Si definimos una excepción de aplicación dentro de un namespace, cuando referenciemos a Exception
, deberemos referenciarla mediante su nombre totalmente cualificado (\Exception
), o utilizando use
:
<?php
namespace \Dwes\Ejemplos;
class AppExcepcion extends \Exception {}
<?php
namespace \Dwes\Ejemplos;
use Exception;
class AppExcepcion extends Exception {}
Excepciones múltiples¶
Se pueden usar excepciones múltiples para comprobar diferentes condiciones. A la hora de capturarlas, se hace de más específica a más general.
<?php
$email = "ejemplo@ejemplo.com";
try {
// Comprueba si el email es válido
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE) {
throw new MiExcepcion($email);
}
// Comprueba la palabra ejemplo en la dirección email
if(strpos($email, "ejemplo") !== FALSE) {
throw new Exception("$email es un email de ejemplo no válido");
}
} catch (MiExcepcion $e) {
echo $e->miFuncion();
} catch(Exception $e) {
echo $e->getMessage();
}
Si en el mismo catch
queremos capturar varias excepciones, hemos de utilizar el operador |
:
<?php
class MainException extends Exception {}
class SubException extends MainException {}
try {
throw new SubException("Lanzada SubException");
} catch (MainException | SubException $e ) {
echo "Capturada Exception " . $e->getMessage();
}
Desde PHP 7, existe el tipo Throwable
, el cual es un interfaz que implementan tanto los errores como las excepciones, y nos permite capturar los dos tipos a la vez:
<?php
try {
// tu codigo
} catch (Throwable $e) {
echo 'Forma de capturar errores y excepciones a la vez';
}
Si sólo queremos capturar los errores fatales, podemos hacer uso de la clase Error
:
<?php
try {
// Genera una notificación que no se captura
echo $variableNoAsignada;
// Error fatal que se captura
funcionQueNoExiste();
} catch (Error $e) {
echo "Error capturado: " . $e->getMessage();
}
Relanzar excepciones¶
En las aplicaciones reales, es muy común capturar una excepción de sistema y lanzar una de aplicación que hemos definido nosotros.
También podemos lanzar las excepciones sin necesidad de estar dentro de un try/catch
.
<?php
class AppException extends Exception {}
try {
// Código de negocio que falla
} catch (Exception $e) {
throw new AppException("AppException: ".$e->getMessage(), $e->getCode(), $e);
}
SPL¶
Standard PHP Library es el conjunto de funciones y utilidades que ofrece PHP, como:
- Estructuras de datos
- Pila, cola, cola de prioridad, lista doblemente enlazada, etc...
- Conjunto de iteradores diseñados para recorrer estructuras agregadas
- arrays, resultados de bases de datos, árboles XML, listados de directorios, etc.
Podéis consultar la documentación en https://www.php.net/manual/es/book.spl.php.
También define un conjunto de excepciones que podemos utilizar para que las lancen nuestras aplicaciones:
LogicException
(extends Exception
)BadFunctionCallException
BadMethodCallException
DomainException
InvalidArgumentException
LengthException
OutOfRangeException
RuntimeException
(extends Exception
)OutOfBoundsException
OverflowException
RangeException
UnderflowException
UnexpectedValueException
También podéis consultar la documentación de estas excepciones.
Actividades¶
-
PR 316. (RA3 / CE3b CE3d CE3g / IC2 / 5p) - El CTO del proyecto insta a que se implemente un control de excepciones óptimo en todo lo que se ha desarrollado hasta el momento. Para ello, se pide crear una excepción de aplicación padre, y luego al menos una que herede de ella por cada servicio que ofrezca la aplicación.
-
RE 317 (RA3 / CE3a, CE3b, CE3c, CE3d, CE3e, CE3f, CE3g / IC2 / 20p) Una vez finalizamos el bloque de introducción a PHP orientado a objetos, ya estamos en condiciones de afrontar el Reto 1. Para ello, a partir del informe realizado en la actividad 221, deberás entregar:
- Clases generadas.
- Diseño.
- Prueba de funcionamiento.
En las fechas indicadas por el docente, se entregará un informe con los diferentes artefactos generados y presentará mediante video el prototipo desarrollado.
Se utilizará una rúbrica para su evaluación en base a la siguiente lista de cotejo:
- Uso de una clase padre y empleo de herencia para la definición de las clases del dominio.
- Uso de métodos encadenados
- Separación de la lógica en diferentes métodos para un bajo acoplamiento
- Se emplea una nomenclatura adecuada para las clases, métodos y propiedades.
- Mecanismos de mantenimiento de estado e información del cliente web.
- Manejo de estructuras y formularios en PHP.
- Programación Orientada a Objetos.