W3docs

Entendiendo las Excepciones en PHP

En PHP, las excepciones se usan para manejar errores inesperados y problemas en tiempo de ejecución. Aprende a lanzar, capturar y crear excepciones.

Una excepción es un objeto que representa un error o una condición inesperada que interrumpe el flujo normal de tu programa. En lugar de devolver un código de error que el llamador podría olvidar comprobar, el código "lanza" una excepción; el entorno de ejecución entonces deshace la pila de llamadas hasta encontrar un bloque catch coincidente. Si ningún bloque la captura, el script se detiene con un error fatal.

Este capítulo cubre cómo lanzar y capturar excepciones, los métodos que expone toda excepción (getMessage(), getCode(), getLine(), getFile()), el bloque finally, múltiples bloques catch, clases de excepción personalizadas y la diferencia entre Exception y Error.

¿Qué es una Excepción en PHP?

Una excepción en PHP es un objeto que desciende de la clase integrada Exception (o, de forma más amplia, de la interfaz Throwable). Cuando algo falla — un archivo que no existe, un argumento no válido, una conexión a la base de datos fallida — se crea uno de estos objetos y se lanza con throw. Lanzar detiene inmediatamente la ruta de ejecución actual y transfiere el control al manejador envolvente más cercano.

Usa una excepción cuando una función no puede continuar de forma significativa y el llamador es el lugar adecuado para decidir qué hacer a continuación. No las uses para el flujo de control ordinario (una búsqueda normal de "usuario no encontrado" se expresa mejor con un valor de retorno).

Lanzar una Excepción

La palabra clave throw genera una excepción, seguida de una nueva instancia de una clase de excepción. El constructor acepta un mensaje opcional, un código entero y una excepción anterior (para encadenamiento):

<?php

function divide(int $a, int $b): float
{
    if ($b === 0) {
        throw new InvalidArgumentException('Division by zero is not allowed.');
    }
    return $a / $b;
}

try {
    echo divide(10, 0);
} catch (InvalidArgumentException $e) {
    echo 'Error: ' . $e->getMessage();
}
?>

Salida:

Error: Division by zero is not allowed.

El código dentro de try se ejecuta normalmente hasta que se dispara throw. A partir de ese punto, el resto del bloque try se omite y se ejecuta el bloque catch correspondiente.

Manejo de Excepciones con try / catch

Se envuelve el código que podría fallar en un bloque try y se recupera del fallo en un bloque catch. La variable en catch (aquí $e) contiene el objeto de excepción, que expone varios métodos de solo lectura:

MétodoDevuelve
getMessage()El mensaje legible por humanos
getCode()El código entero pasado al constructor
getLine()La línea donde se lanzó la excepción
getFile()El archivo donde se lanzó
getPrevious()La excepción "anterior" encadenada, si existe
getTraceAsString()La traza de la pila como cadena de texto
<?php

try {
    throw new Exception('Something failed', 42);
} catch (Exception $e) {
    echo 'Message: ' . $e->getMessage() . PHP_EOL;
    echo 'Code: ' . $e->getCode() . PHP_EOL;
}
?>

Salida:

Message: Something failed
Code: 42

Captura de Múltiples Tipos de Excepciones

Un único bloque try puede tener varios bloques catch. PHP los verifica de arriba a abajo y ejecuta el primero cuyo tipo coincide. Desde PHP 7.1 también se pueden capturar varios tipos no relacionados en un bloque usando el operador tubería (|):

<?php

try {
    throw new RuntimeException('Network is down');
} catch (InvalidArgumentException $e) {
    echo 'Bad argument: ' . $e->getMessage();
} catch (RuntimeException | LogicException $e) {
    echo 'Runtime/logic problem: ' . $e->getMessage();
}
?>

Salida:

Runtime/logic problem: Network is down

El orden importa: lista los tipos de excepción más específicos antes que sus clases padre, de lo contrario el catch genérico lo absorberá todo primero.

El Bloque finally

El bloque finally es opcional pero útil. Su código siempre se ejecuta — tanto si se lanzó una excepción como si no, e incluso si el bloque try o catch ejecuta un return. Esto lo convierte en el lugar adecuado para tareas de limpieza como cerrar un manejador de archivos o liberar un bloqueo:

<?php

try {
    echo 'Open resource' . PHP_EOL;
    throw new Exception('Boom');
} catch (Exception $e) {
    echo 'Caught: ' . $e->getMessage() . PHP_EOL;
} finally {
    echo 'Cleanup always runs' . PHP_EOL;
}
?>

Salida:

Open resource
Caught: Boom
Cleanup always runs

Clases de Excepción Personalizadas

Más allá de los tipos integrados, puedes definir tus propias clases de excepción extendiendo Exception. Una clase personalizada te permite llevar datos adicionales (como un valor fallido) y permite a los llamadores capturar tu tipo de error específico sin atrapar accidentalmente otros no relacionados:

<?php

class InsufficientFundsException extends Exception
{
    private float $shortfall;

    public function __construct(float $shortfall)
    {
        $this->shortfall = $shortfall;
        parent::__construct("Short by $shortfall");
    }

    public function getShortfall(): float
    {
        return $this->shortfall;
    }
}

try {
    throw new InsufficientFundsException(25.5);
} catch (InsufficientFundsException $e) {
    echo $e->getMessage() . PHP_EOL;
    echo 'Need ' . $e->getShortfall() . ' more.';
}
?>

Salida:

Short by 25.5
Need 25.5 more.

PHP también incluye una familia de excepciones SPL ya listas — InvalidArgumentException, RuntimeException, LengthException y otras — por lo que a menudo no necesitas crear las tuyas propias.

Exception vs. Error

Desde PHP 7, los fallos internos del motor (como un error de tipo o llamar a un método no definido) se lanzan como objetos Error, no como objetos Exception. Ambos implementan la interfaz Throwable. Un simple catch (Exception $e) no capturará un Error. Para manejar ambos, captura la interfaz:

<?php

try {
    $result = 10 % 0; // throws a DivisionByZeroError
} catch (Throwable $e) {
    echo get_class($e) . ': ' . $e->getMessage();
}
?>

Salida:

DivisionByZeroError: Modulo by zero

Como regla general, reserva Exception para problemas de los que tu aplicación puede recuperarse, y deja que Error represente errores que deberías corregir en lugar de capturar.

Temas Relacionados

Conclusión

Las excepciones proporcionan a PHP una forma estructurada de tratar los fallos: una función lanza con throw cuando no puede continuar, y el llamador usa catch para recuperarse, registrar o relanzar. Combina try, catch y finally para separar el camino feliz del manejo de errores y la limpieza, usa clases personalizadas para modelar los fallos de tu dominio y recuerda que los problemas a nivel del motor llegan como Error (capturable vía Throwable). Practicar estos patrones en tus propios proyectos hará que tu código sea mucho más robusto.

Práctica

Práctica
¿Qué es cierto sobre las Excepciones en PHP según la información de la URL proporcionada?
¿Qué es cierto sobre las Excepciones en PHP según la información de la URL proporcionada?
Was this page helpful?