Tipos de Errores en PHP
PHP tiene un sistema de errores que clasifica los problemas según su gravedad. Entender estos tipos te ayudará a depurar tu código y a configurar correctamente el reporte de errores en desarrollo y producción.
Niveles de error en PHP
PHP clasifica los errores en diferentes niveles según su impacto en la ejecución:
| Constante | Descripción | ¿Detiene ejecución? |
|---|---|---|
E_ERROR |
Error fatal. Problema grave irrecuperable. | Sí |
E_WARNING |
Advertencia. Algo salió mal pero puede continuar. | No |
E_NOTICE |
Aviso. Posible problema, código sigue ejecutándose. | No |
E_PARSE |
Error de sintaxis. El código no puede interpretarse. | Sí |
E_DEPRECATED |
Funcionalidad obsoleta que será eliminada. | No |
E_STRICT |
Sugerencias para mejorar compatibilidad. | No |
Errores fatales (E_ERROR)
Detienen la ejecución inmediatamente. No hay forma de continuar después de un error fatal:
<?php
declare(strict_types=1);
// Llamar a una función que no existe
funcionQueNoExiste();
// Fatal error: Uncaught Error: Call to undefined function
// Instanciar una clase que no existe
$objeto = new ClaseInexistente();
// Fatal error: Uncaught Error: Class "ClaseInexistente" not found
// Agotar la memoria
ini_set('memory_limit', '1M');
$array = range(1, 10000000);
// Fatal error: Allowed memory size exhausted
Advertencias (E_WARNING)
Indican un problema pero permiten que el script continúe. Es importante corregirlas porque pueden causar comportamientos inesperados:
<?php
declare(strict_types=1);
// Incluir un archivo que no existe
include 'archivo_inexistente.php';
// Warning: include(archivo_inexistente.php): Failed to open stream
// El script continúa ejecutándose
// División por cero (PHP 8+: ahora es DivisionByZeroError)
// En versiones anteriores era warning
$resultado = 10 / 0;
// Argumento incorrecto a una función
$array = 'no soy un array';
$longitud = count($array);
// Warning: count(): Parameter must be an array or Countable
echo 'Este código sí se ejecuta después del warning';
Avisos (E_NOTICE)
Son los errores menos graves pero no deben ignorarse. Suelen indicar malas prácticas o posibles bugs:
<?php
declare(strict_types=1);
// Acceder a variable no definida (PHP 8+: ahora es Warning)
echo $variableNoDefinida;
// Warning: Undefined variable $variableNoDefinida
// Acceder a índice de array inexistente (PHP 8+: ahora es Warning)
$array = ['a' => 1, 'b' => 2];
echo $array['c'];
// Warning: Undefined array key "c"
// Forma correcta: verificar antes de acceder
if (isset($array['c'])) {
echo $array['c'];
}
// O usar operador null coalescence
echo $array['c'] ?? 'valor por defecto';
Muchos errores que antes eran
E_NOTICE ahora son
E_WARNING en PHP 8. Algunos
warnings se convirtieron en
Error o
TypeError.
Errores de sintaxis (E_PARSE)
Ocurren cuando el código tiene errores de sintaxis. PHP no puede ni siquiera empezar a ejecutar el script:
<?php
// Falta punto y coma
$nombre = 'Ana'
echo $nombre;
// Parse error: syntax error, unexpected token "echo"
// Paréntesis sin cerrar
if ($edad > 18 {
echo 'Mayor de edad';
}
// Parse error: syntax error, unexpected token "{"
// Comillas sin cerrar
$mensaje = 'Hola mundo;
// Parse error: syntax error, unexpected end of file
Configurar el reporte de errores
PHP permite configurar qué errores se muestran y cómo. Esto es crucial para diferenciar entre desarrollo y producción:
<?php
declare(strict_types=1);
// Mostrar TODOS los errores (recomendado en desarrollo)
error_reporting(E_ALL);
ini_set('display_errors', '1');
// Mostrar solo errores y warnings (sin notices)
error_reporting(E_ERROR | E_WARNING);
// Mostrar todos excepto notices
error_reporting(E_ALL & ~E_NOTICE);
// Mostrar todos excepto notices y deprecated
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
// No mostrar ningún error (NUNCA en desarrollo)
error_reporting(0);
// Verificar el nivel actual
$nivel = error_reporting();
echo "Nivel actual: $nivel";
Configuración recomendada
<?php
declare(strict_types=1);
// config.php - Configuración según el entorno
$entorno = getenv('APP_ENV') ?: 'development';
if ($entorno === 'development') {
// DESARROLLO: ver todos los errores
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
} else {
// PRODUCCIÓN: ocultar errores, solo registrar en log
error_reporting(E_ALL);
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/var/log/php/errors.log');
}
El operador de supresión @
El operador @ suprime los errores
de una expresión.
Evita usarlo porque oculta
problemas reales:
<?php
declare(strict_types=1);
// MAL: suprimir errores con @
$contenido = @file_get_contents('archivo.txt');
// BIEN: manejar el error correctamente
$archivo = 'archivo.txt';
if (file_exists($archivo) && is_readable($archivo)) {
$contenido = file_get_contents($archivo);
} else {
$contenido = null;
// Manejar el caso de archivo no disponible
}
// MEJOR: usar excepciones (lo veremos en la siguiente lección)
try {
$contenido = file_get_contents($archivo);
if ($contenido === false) {
throw new RuntimeException("No se pudo leer: $archivo");
}
} catch (RuntimeException $e) {
// Manejar el error
$contenido = null;
}
Errores vs Excepciones en PHP 8
PHP 8 convirtió muchos errores fatales en excepciones que pueden capturarse. Esto da más control sobre el manejo de errores:
<?php
declare(strict_types=1);
// TypeError: tipo de argumento incorrecto
function saludar(string $nombre): void
{
echo "Hola, $nombre";
}
try {
saludar(123); // Pasamos int en lugar de string
} catch (TypeError $e) {
echo 'Error de tipo: ' . $e->getMessage();
}
// ArgumentCountError: número incorrecto de argumentos
function sumar(int $a, int $b): int
{
return $a + $b;
}
try {
sumar(1); // Falta un argumento
} catch (ArgumentCountError $e) {
echo 'Faltan argumentos: ' . $e->getMessage();
}
// DivisionByZeroError
try {
$resultado = 10 % 0; // Módulo por cero
} catch (DivisionByZeroError $e) {
echo 'División por cero: ' . $e->getMessage();
}
Jerarquía de Throwable
En PHP 7+, todos los errores y excepciones
implementan la interfaz Throwable:
Throwable (interfaz)
├── Error (errores internos de PHP)
│ ├── TypeError
│ ├── ArgumentCountError
│ ├── ArithmeticError
│ │ └── DivisionByZeroError
│ ├── ParseError
│ └── AssertionError
│
└── Exception (excepciones de usuario)
├── RuntimeException
├── InvalidArgumentException
├── LogicException
└── ... (muchas más)
<?php
declare(strict_types=1);
// Capturar cualquier error o excepción
try {
// Código que puede fallar
$resultado = operacionRiesgosa();
} catch (Throwable $t) {
// Captura tanto Error como Exception
echo 'Algo falló: ' . $t->getMessage();
}
// Capturar por separado
try {
$resultado = operacionRiesgosa();
} catch (TypeError $e) {
echo 'Error de tipo';
} catch (Exception $e) {
echo 'Excepción: ' . $e->getMessage();
} catch (Error $e) {
echo 'Error interno: ' . $e->getMessage();
}
Ejercicios
Ejercicio 1: Configurar entorno
Crea un archivo
config.php que configure el
reporte de errores según una constante
DEBUG. Si es
true, mostrar todos los
errores. Si es false, solo
registrarlos en un archivo de log.
Ver solución
<?php
declare(strict_types=1);
// config.php
define('DEBUG', true); // Cambiar a false en producción
error_reporting(E_ALL);
if (DEBUG) {
// DESARROLLO: mostrar todos los errores
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
} else {
// PRODUCCIÓN: ocultar errores, registrar en log
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', __DIR__ . '/logs/errores.log');
}
Ejercicio 2: Identificar tipos de error
Escribe código que genere
intencionalmente: un Warning (incluir
archivo inexistente con
include), un TypeError
(pasar tipo incorrecto a función
tipada), y un Error por variable
indefinida. Captura cada uno y muestra
un mensaje descriptivo.
Ver solución
<?php
declare(strict_types=1);
// 1. Warning: incluir archivo inexistente
echo "--- Warning ---\n";
$resultado = @include 'archivo_que_no_existe.php';
if ($resultado === false) {
echo "Warning capturado: archivo no encontrado\n";
}
// 2. TypeError: tipo incorrecto
echo "\n--- TypeError ---\n";
function saludar(string $nombre): string
{
return "Hola, $nombre";
}
try {
saludar(123);
} catch (TypeError $e) {
echo "TypeError capturado: " . $e->getMessage() . "\n";
}
// 3. Warning por variable indefinida
echo "\n--- Variable indefinida ---\n";
$valor = $variableNoDefinida ?? 'valor por defecto';
echo "Manejado con ??: $valor\n";
Ejercicio 3: Reemplazar @ por manejo correcto
Dado este código que usa el operador de
supresión:
$json = @json_decode($input);, reescríbelo para manejar el error
correctamente usando
json_last_error() y
lanzando una excepción si el JSON es
inválido.
Ver solución
<?php
declare(strict_types=1);
function decodificarJson(string $input): mixed
{
$datos = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new InvalidArgumentException(
'JSON inválido: ' . json_last_error_msg()
);
}
return $datos;
}
// Prueba con JSON válido
try {
$resultado = decodificarJson('{"nombre": "Ana", "edad": 25}');
print_r($resultado);
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
}
// Prueba con JSON inválido
try {
$resultado = decodificarJson('{"nombre": "Ana", edad: 25}');
} catch (InvalidArgumentException $e) {
echo "Error: " . $e->getMessage();
// Error: JSON inválido: Syntax error
}
¿Has encontrado un error o tienes sugerencias para esta lección?
Enviar feedback¿Te está gustando el curso?
Tenemos cursos premium con proyectos reales y soporte.
Descubrir cursos premium