set_error_handler()
Aprende a usar set_error_handler() en PHP para interceptar errores no fatales y aplicar tu propia lógica de registro o manejo.
El comportamiento predeterminado de PHP ante un error no fatal es imprimir un mensaje en la salida (o registrarlo) y continuar la ejecución. Eso rara vez es lo que quieres en producción: el mensaje sin procesar puede filtrar rutas de archivo a los visitantes, y no tienes un lugar centralizado para registrar, formatear o convertir errores. La función set_error_handler() resuelve esto enrutando los errores incorporados de PHP a través de una función que tú controlas.
Este capítulo explica qué hace set_error_handler(), la firma exacta del callback que PHP espera, qué errores puede y no puede interceptar, y cómo usarlo para un registro limpio.
Qué hace set_error_handler()
set_error_handler() registra un callback que PHP invoca en lugar de su manejador de errores incorporado cada vez que se produce un error coincidente (no fatal). Tu callback decide qué ocurre a continuación: registrarlo, mostrar un mensaje amigable, lanzar una excepción o ignorarlo silenciosamente.
No detiene que los errores sean generados; solo cambia cómo son manejados. PHP sigue respetando error_reporting al decidir si llamar a tu manejador.
Sintaxis
set_error_handler(
callable|null $callback,
int $error_levels = E_ALL
): callable|false| Parámetro | Descripción |
|---|---|
$callback | La función que PHP llama cuando se produce un error. Pasa null para restaurar el manejador incorporado de PHP. |
$error_levels | Una máscara de bits de los niveles de error que tu manejador debe recibir (ej. E_WARNING | E_NOTICE). Por defecto es E_ALL. |
Valor de retorno: el manejador previamente registrado (un callable), o null si no había ninguno. Devuelve false solo cuando el callback es inválido.
La firma del callback
PHP llama a tu manejador con hasta cinco argumentos. Los primeros cuatro son los que más utilizarás:
function handler(
int $errno, // the error level constant, e.g. E_WARNING
string $errstr, // the error message
string $errfile = "", // file where the error occurred
int $errline = 0 // line number
): bool {
// ...
}Si tu manejador devuelve false, PHP continúa con su manejo de errores interno normal después. Devolver true (o nada) le indica a PHP que el error ha sido completamente manejado y suprime el comportamiento predeterminado.
Qué errores puede capturar
set_error_handler() intercepta los niveles de error capturables por el usuario — advertencias, avisos, deprecaciones y la familia E_USER_* generada por trigger_error():
| Capturable | No capturable (fatal) |
|---|---|
E_WARNING, E_NOTICE, E_DEPRECATED | E_ERROR |
E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE | E_PARSE |
E_RECOVERABLE_ERROR, E_STRICT | E_CORE_ERROR, E_COMPILE_ERROR |
Nota: Los errores fatales como
E_ERRORyE_PARSEevitan tu manejador y terminan el script. Para capturar esos, combina tu manejador conset_exception_handler()y una función de apagado. Las excepciones no capturadas tampoco se enrutan aquí — tienen su propio manejador.
Un manejador básico
Define una función con la firma esperada y regístrala. Aquí una llamada a trigger_error() simula una advertencia para que puedas ver el manejador en acción:
<?php
function customErrorHandler($errno, $errstr, $errfile, $errline)
{
echo "Handled error [$errno]: $errstr in $errfile on line $errline\n";
return true; // we consider the error fully handled
}
set_error_handler("customErrorHandler");
trigger_error("This is a test warning", E_USER_WARNING);
// Restore PHP's default error handling
restore_error_handler();Salida:
Handled error [512]: This is a test warning in ... on line 11512 es el valor numérico de E_USER_WARNING. Después de restore_error_handler(), los errores vuelven al comportamiento predeterminado de PHP.
Convertir errores en excepciones
Un patrón común en producción es convertir advertencias y avisos en excepciones para que fluyan a través de tu lógica normal de try/catch. Esto te permite manejar un file_get_contents() fallido (que solo emite una advertencia) con try/catch:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// Respect the @ operator and error_reporting settings.
if (!(error_reporting() & $errno)) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
$data = file_get_contents("/no/such/file");
} catch (ErrorException $e) {
echo "Caught: " . $e->getMessage() . "\n";
}Salida:
Caught: file_get_contents(/no/such/file): Failed to open stream: No such file or directoryRegistrar en lugar de mostrar
Mapear la constante de nivel a una etiqueta legible mantiene los registros fáciles de escanear. Usa error_log() para escribir en tu destino de registro configurado:
<?php
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
$levels = [
E_WARNING => "WARNING",
E_NOTICE => "NOTICE",
E_DEPRECATED => "DEPRECATED",
E_USER_WARNING => "USER_WARNING",
];
$label = $levels[$errno] ?? "UNKNOWN($errno)";
$line = "[$label] $errstr in $errfile:$errline";
error_log($line); // goes to your log, not the page
echo $line . "\n"; // shown here only to demonstrate the output
return true;
});
trigger_error("Disk space low", E_USER_WARNING);Salida:
[USER_WARNING] Disk space low in ... :15Aspectos a tener en cuenta
- El operador
@. Cuando un error es silenciado con@,error_reporting()devuelve0dentro de tu manejador. Compruebaerror_reporting() & $errnosi quieres respetar@, como se muestra arriba. - Los errores fatales siguen escapando. Sin importar el segundo argumento,
E_ERRORy los errores de análisis nunca se entregan a tu manejador. - Es global. Un manejador registrado afecta a toda la solicitud. Las bibliotecas que establecen su propio manejador pueden sobrescribir el tuyo, así que restaura los manejadores cuando hayas terminado.
- No uses
echoen producción. Mostrar mensajes sin procesar filtra rutas y ayuda a los atacantes — regístralos y muestra en su lugar una página genérica.
Funciones relacionadas
restore_error_handler()— revertir al manejador anterior.trigger_error()— generar tus propios erroresE_USER_*.error_reporting()— controlar qué niveles están activos.set_exception_handler()— capturar excepciones no capturadas.
Conclusión
set_error_handler() te da un lugar único para interceptar los errores no fatales de PHP y aplicar tu propia lógica: registrarlos, convertirlos en excepciones u ocultarlos de los usuarios. Combínalo con un manejador de excepciones y un registro adecuado para un manejo de errores de nivel productivo. Recuerda su único límite: los errores fatales y de análisis lo evitan por completo.