W3docs

throw

En PHP, la palabra clave "throw" se usa para lanzar una excepción. Las excepciones permiten manejar errores y condiciones inesperadas en tu código.

La palabra clave throw en PHP

La palabra clave throw detiene la ejecución normal en el punto donde se ejecuta y lanza una excepción — un objeto que señala que algo salió mal. El control salta inmediatamente fuera de la función actual y sube por la pila de llamadas hasta encontrar un bloque catch coincidente. Si ningún catch coincide, PHP detiene el script con un error fatal.

Esta página cubre la sintaxis de throw, cuándo usarlo en lugar de devolver un valor de error, cómo lanzar excepciones integradas y personalizadas, cómo relanzar y encadenar excepciones, y la característica de PHP 8 que permite usar throw como expresión. Para una visión más amplia, consulta Excepciones en PHP y el flujo try/catch/finally.

Sintaxis

throw new Exception("Error message here");

A throw se le debe pasar un valor que sea una instancia de Throwable — en la práctica una Exception (o una de sus subclases) o un Error. La cadena pasada al constructor se convierte en el mensaje de la excepción, que se puede leer posteriormente con getMessage().

Como una excepción lanzada desenreda la pila, cualquier código después de throw en el mismo bloque nunca se ejecuta:

throw new Exception("stop here");
echo "this line is unreachable"; // never executes

¿Por qué usar throw en lugar de devolver un error?

Devolver un valor especial (como false o -1) para señalar un fallo obliga a cada llamador a recordar verificarlo, y el significado del valor es fácil de perder. throw hace que el fallo sea imposible de ignorar: la excepción se propaga automáticamente hasta que algo la maneje, y lleva consigo un mensaje, un código, un seguimiento de la pila y el archivo y línea donde ocurrió.

Usa throw para condiciones excepcionales de las que la función actual no puede recuperarse sensatamente — argumentos inválidos, una conexión a base de datos fallida, un archivo requerido que no existe — y deja que un llamador de nivel superior decida qué hacer.

Un ejemplo básico

Aquí una función divide() lanza una excepción al intentar dividir por cero, y el llamador la captura:

<?php

function divide(int $numerator, int $denominator): float
{
    if ($denominator === 0) {
        throw new InvalidArgumentException("Cannot divide by zero.");
    }
    return $numerator / $denominator;
}

try {
    echo divide(10, 2), PHP_EOL; // 5
    echo divide(10, 0), PHP_EOL; // throws before printing
} catch (InvalidArgumentException $e) {
    echo "Caught: " . $e->getMessage() . PHP_EOL;
}

Salida:

5
Caught: Cannot divide by zero.

La primera llamada tiene éxito e imprime 5. La segunda lanza una excepción, por lo que su echo nunca se ejecuta y el control salta directamente al bloque catch.

Lanzar una excepción personalizada

Extender Exception permite dar a cada tipo de error su propio nombre, de modo que los llamadores puedan capturar exactamente los fallos que les interesan e ignorar el resto:

<?php

class InsufficientFundsException extends Exception {}

function withdraw(float $balance, float $amount): float
{
    if ($amount > $balance) {
        throw new InsufficientFundsException(
            "Cannot withdraw $amount; balance is only $balance."
        );
    }
    return $balance - $amount;
}

try {
    echo withdraw(100, 250), PHP_EOL;
} catch (InsufficientFundsException $e) {
    echo "Declined: " . $e->getMessage() . PHP_EOL;
}

Salida:

Declined: Cannot withdraw 250; balance is only 100.

Consulta Clases de excepción personalizadas para más información sobre cómo extender Exception.

Mensaje, código y excepción previa de la excepción

El constructor de Exception acepta tres argumentos — message, code y una excepción previous. El tercero te permite envolver un error de bajo nivel en uno más significativo sin perder la causa original (esto se llama encadenamiento de excepciones):

<?php

try {
    try {
        throw new RuntimeException("Disk read failed", 13);
    } catch (RuntimeException $low) {
        // Re-throw a higher-level exception, keeping the original as the cause.
        throw new Exception("Could not load config", 0, $low);
    }
} catch (Exception $e) {
    echo $e->getMessage() . PHP_EOL;                 // Could not load config
    echo "Caused by: " . $e->getPrevious()->getMessage() . PHP_EOL; // Disk read failed
    echo "Original code: " . $e->getPrevious()->getCode() . PHP_EOL; // 13
}

Salida:

Could not load config
Caused by: Disk read failed
Original code: 13

Relanzar en un bloque catch

No es necesario manejar completamente una excepción donde se captura. Un bloque catch puede realizar algún trabajo (registrarla, añadir contexto) y luego lanzar throw nuevamente para que un manejador externo termine el trabajo:

<?php

function loadUser(int $id): array
{
    try {
        throw new RuntimeException("Database is down");
    } catch (RuntimeException $e) {
        error_log("loadUser($id) failed: " . $e->getMessage());
        throw $e; // pass it on
    }
}

try {
    loadUser(7);
} catch (RuntimeException $e) {
    echo "Handled at top level: " . $e->getMessage() . PHP_EOL;
}

Salida:

Handled at top level: Database is down

throw como expresión (PHP 8+)

Desde PHP 8.0, throw es una expresión, no solo una sentencia, por lo que puedes usarlo en lugares que esperan un valor — como los operadores ?: y ?? o una función flecha:

<?php

function getConfig(array $config, string $key): string
{
    // Throw inline when the key is missing.
    return $config[$key] ?? throw new InvalidArgumentException("Missing key: $key");
}

echo getConfig(['env' => 'prod'], 'env'), PHP_EOL; // prod

try {
    getConfig(['env' => 'prod'], 'region');
} catch (InvalidArgumentException $e) {
    echo $e->getMessage() . PHP_EOL;
}

Salida:

prod
Missing key: region

Errores comunes

  • Lanzar sin un try/catch en ningún punto de la pila. Una excepción no capturada se convierte en un error fatal y detiene el script. Captúrala siempre en algún lugar, o registra un manejador alternativo con set_exception_handler().
  • Lanzar una cadena o un array. throw requiere un objeto que implemente Throwable; throw "oops"; es un error de sintaxis.
  • Silenciar excepciones. Un bloque catch vacío oculta errores. Como mínimo registra el mensaje o vuelve a lanzar la excepción.
  • Usar excepciones para el flujo de control ordinario. Lanzar en cada rama esperada (por ejemplo, "usuario no encontrado" durante una búsqueda rutinaria) es lento y confuso — reserva las excepciones para casos verdaderamente excepcionales.

Resumen

  • throw lanza un Throwable y desenreda inmediatamente la pila hasta el catch coincidente más cercano.
  • Prefiérelo sobre valores de retorno especiales para que los fallos no puedan ignorarse silenciosamente.
  • Subclasifica Exception para crear tipos de error con nombre; pasa una excepción previous para encadenar causas.
  • Captura, añade contexto y vuelve a usar throw para que un manejador externo decida.
  • En PHP 8+, throw funciona como expresión dentro de ??, ?: y funciones flecha.

Continúa con el bloque try, el bloque catch y finally para ver el ciclo completo de manejo de excepciones.

Práctica

Práctica
¿Qué hace la sentencia 'throw' en PHP?
¿Qué hace la sentencia 'throw' en PHP?
Was this page helpful?