catch
Aprende a usar la palabra clave catch en PHP para capturar y manejar excepciones lanzadas dentro de un bloque try.
La palabra clave catch en PHP
Cuando el código dentro de un bloque try encuentra una excepción — un objeto que indica que algo salió mal — la ejecución se detiene y PHP busca un bloque catch coincidente para manejarla. La palabra clave catch especifica el tipo de excepción que puede gestionar y enlaza el objeto lanzado a una variable para que puedas inspeccionarlo. Sin un catch, una excepción no capturada se convierte en un error fatal y detiene el script.
Esta página explica la sintaxis de catch, cómo PHP elige qué bloque se ejecuta, cómo leer detalles de la excepción capturada y los patrones comunes (múltiples catches, tipos unión, relanzamiento) que usarás en código real.
Sintaxis
Un bloque catch siempre sigue a un bloque try. Declara un tipo de excepción y una variable que recibe el objeto lanzado:
<?php
try {
// Code that may throw an exception
} catch (Exception $e) {
// Runs only if a matching exception is thrown above
echo $e->getMessage();
}PHP hace coincidir un bloque catch cuando el objeto lanzado es una instancia del tipo declarado. Dado que toda excepción integrada extiende la clase base Exception (y ambas extienden la interfaz Throwable), catch (Exception $e) captura la mayoría de las excepciones. Capturar Throwable también intercepta objetos Error como TypeError y DivisionByZeroError.
Puedes combinar catch con un bloque finally para ejecutar código de limpieza tanto si se produjo una excepción como si no.
Un ejemplo funcional
La función siguiente lanza una excepción cuando se le pide dividir entre cero. El bloque catch intercepta esa excepción y la reporta en lugar de dejar que el script falle:
<?php
function divide($numerator, $denominator)
{
if ($denominator == 0) {
throw new InvalidArgumentException("Division by zero.");
}
return $numerator / $denominator;
}
try {
echo divide(10, 0);
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
// Output: Error: Division by zero.Observa que el script continúa ejecutándose después del catch — el control se reanuda en la línea siguiente a la estructura try/catch en lugar de abortar.
Leer detalles de la excepción capturada
La variable en una cláusula catch ($e en el ejemplo) es el propio objeto exception. Expone métodos que describen lo que ocurrió:
<?php
try {
throw new RuntimeException("Disk is full", 28);
} catch (RuntimeException $e) {
echo $e->getMessage(); // Disk is full
echo "\n";
echo $e->getCode(); // 28
echo "\n";
echo $e->getLine(); // 4 (line where it was thrown)
}| Método | Devuelve |
|---|---|
getMessage() | El mensaje de error legible por humanos |
getCode() | El código de error entero pasado al constructor |
getFile() | El archivo en el que se creó la excepción |
getLine() | El número de línea donde se lanzó |
getTrace() | La traza de pila como un array |
getPrevious() | La excepción anterior (para excepciones encadenadas) |
Capturar múltiples tipos de excepción
Cuando un bloque try puede fallar de distintas maneras, lista varios bloques catch. PHP los evalúa de arriba a abajo y ejecuta el primero que coincide, así que ordena los tipos más específicos antes que los generales:
<?php
try {
// Code that may throw different exceptions
throw new InvalidArgumentException("bad input");
} catch (InvalidArgumentException $e) {
echo "Invalid argument: " . $e->getMessage();
} catch (RuntimeException $e) {
echo "Runtime problem: " . $e->getMessage();
} catch (Exception $e) {
echo "Something else: " . $e->getMessage();
}
// Output: Invalid argument: bad inputSi catch (Exception $e) apareciera primero, capturaría todo y los bloques más específicos situados debajo nunca se ejecutarían.
Union catch (PHP 7.1+)
Cuando dos tipos de excepción distintos necesitan el mismo manejo, combínalos con una barra vertical | en lugar de duplicar el bloque:
<?php
try {
throw new RuntimeException("connection reset");
} catch (InvalidArgumentException | RuntimeException $e) {
echo "Handled: " . $e->getMessage();
}
// Output: Handled: connection resetcatch sin captura (PHP 8.0+)
Si no necesitas el objeto de excepción, puedes omitir la variable por completo:
<?php
try {
throw new Exception("ignored details");
} catch (Exception) {
echo "An error occurred, retrying...";
}
// Output: An error occurred, retrying...Relanzamiento y encadenamiento de excepciones
A veces un bloque catch debe registrar el problema y luego propagarlo — o envolver una excepción de bajo nivel en una más significativa. Pasa la original como tercer argumento del constructor para preservar la cadena:
<?php
try {
try {
throw new RuntimeException("low-level failure");
} catch (RuntimeException $e) {
// Wrap and re-throw with context preserved
throw new Exception("High-level operation failed", 0, $e);
}
} catch (Exception $e) {
echo $e->getMessage(); // High-level operation failed
echo "\n";
echo $e->getPrevious()->getMessage(); // low-level failure
}Buenas prácticas
- Captura el tipo más específico que puedas manejar. Un
catch (Throwable $e)general puede ocultar errores al absorber fallos de programación que deberías corregir. - Ordena de específico a general. Las subclases específicas deben preceder a sus tipos padre.
- No dejes un
catchvacío. Descartar silenciosamente una excepción hace que los fallos sean invisibles; como mínimo, regístrala. - Lanza excepciones, no devuelvas códigos de error. Combina
catchconthrowpara que los llamadores no puedan ignorar accidentalmente los fallos. - Usa
finallypara la limpieza (cerrar archivos, liberar bloqueos) que debe ejecutarse tanto en la ruta de éxito como en la de fallo.
Temas relacionados
- PHP
try— el bloque quecatchprotege - PHP
throw— lanzar una excepción - PHP
finally— código de limpieza garantizado - PHP
exception— el objeto de excepción y sus métodos