W3docs

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étodoDevuelve
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 input

Si 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 reset

catch 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 catch vací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 catch con throw para que los llamadores no puedan ignorar accidentalmente los fallos.
  • Usa finally para la limpieza (cerrar archivos, liberar bloqueos) que debe ejecutarse tanto en la ruta de éxito como en la de fallo.

Temas relacionados

Práctica

Práctica
¿Qué ocurre cuando se lanza una excepción y no se captura en PHP?
¿Qué ocurre cuando se lanza una excepción y no se captura en PHP?
Was this page helpful?