Las funciones filter_var() y filter_input() son la forma nativa de PHP para validar y sanitizar datos. Ofrecen filtros predefinidos para los tipos de datos más comunes: emails, URLs, enteros, floats, IPs y booleanos. Este artículo muestra cuándo usarlas, cuándo no son suficientes y el antipatrón más frecuente.
filter_var() para validación
<?php // Validar email $email = '[email protected]'; if (filter_var($email, FILTER_VALIDATE_EMAIL)) { echo "Email válidon"; } // Validar URL $url = 'https://www.php.net/manual/es/'; if (filter_var($url, FILTER_VALIDATE_URL)) { echo "URL válidan"; } // Validar entero con rango $edad = '25'; $edadValida = filter_var($edad, FILTER_VALIDATE_INT, [ 'options' => ['min_range' => 0, 'max_range' => 150], ]); var_dump($edadValida); // int(25) convierte a int si es válido, false si no // Validar IP (v4 e v6) var_dump(filter_var('192.168.1.1', FILTER_VALIDATE_IP)); // string var_dump(filter_var('::1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); // string // Validar float $precio = '29,99'; // coma como separador decimal var_dump(filter_var($precio, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND)); // false var_dump(filter_var('29.99', FILTER_VALIDATE_FLOAT)); // float(29.99) ?>
filter_input(): leer y validar desde superglobales
<?php
// Leer y validar en una sola llamada desde $_GET, $_POST, $_COOKIE, $_SERVER
$pagina = filter_input(INPUT_GET, 'pagina', FILTER_VALIDATE_INT, [
'options' => ['default' => 1, 'min_range' => 1],
]);
// Si 'pagina' no existe o no es entero positivo, devuelve 1 (default)
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
// null si la clave no existe, false si no es email válido
$busqueda = filter_input(INPUT_GET, 'q', FILTER_DEFAULT);
// El valor crudo, sin sanitizar (evita FILTER_SANITIZE_STRING)
?>
Sanitización: qué filtros usar
<?php // FILTER_SANITIZE_EMAIL: elimina caracteres no válidos en emails // (no valida, solo limpia) $emailSucio = 'usuario [at] ejemplo .com'; $emailLimpio = filter_var($emailSucio, FILTER_SANITIZE_EMAIL); echo $emailLimpio; // [email protected] pero ¡no está garantizado que sea válido! // FILTER_SANITIZE_NUMBER_INT: deja solo dígitos, + y - $numero = filter_var('$1.234,56', FILTER_SANITIZE_NUMBER_INT); echo $numero; // 123456 (elimina $, puntos y comas) // FILTER_SANITIZE_URL: elimina caracteres no permitidos en URLs $urlSucia = 'https://ejemplo.com/ruta con espacios'; echo filter_var($urlSucia, FILTER_SANITIZE_URL); // https://ejemplo.com/rutaconspacios cuidado, no es lo que esperas ?>
El antipatrón de FILTER_SANITIZE_STRING
<?php // MAL: FILTER_SANITIZE_STRING fue deprecado en PHP 8.1 // Eliminaba etiquetas HTML y entidades, pero de forma inconsistente // $nombre = filter_var($_POST['nombre'], FILTER_SANITIZE_STRING); // NO USAR // BIEN: usar htmlspecialchars() para escapar HTML al mostrar $nombre = $_POST['nombre'] ?? ''; $nombreSeguro = htmlspecialchars($nombre, ENT_QUOTES | ENT_HTML5, 'UTF-8'); echo $nombreSeguro; // los caracteres < > " ' & quedan escapados // Para escapar en contextos distintos (URL, JS, SQL), usar la función apropiada $url = urlencode($nombre); // para parámetros GET // Para SQL: usar prepared statements, no sanitización de strings ?>
Ejemplo real: procesar formulario de contacto
<?php
function procesarFormularioContacto(array $post): array
{
$errores = [];
$datos = [];
// Nombre: string limpio, no vacío
$nombre = trim($post['nombre'] ?? '');
if (strlen($nombre) < 2 || strlen($nombre) > 100) {
$errores['nombre'] = 'El nombre debe tener entre 2 y 100 caracteres';
} else {
$datos['nombre'] = $nombre;
}
// Email: validación estricta
$email = filter_var(trim($post['email'] ?? ''), FILTER_VALIDATE_EMAIL);
if ($email === false) {
$errores['email'] = 'Email no válido';
} else {
$datos['email'] = $email;
}
// Edad: entero en rango
$edad = filter_var($post['edad'] ?? '', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 18, 'max_range' => 120],
]);
if ($edad === false) {
$errores['edad'] = 'Debes tener entre 18 y 120 años';
} else {
$datos['edad'] = $edad;
}
return ['errores' => $errores, 'datos' => $datos];
}
?>
La documentación oficial de filter_var() y la lista completa de filtros disponibles muestran todas las opciones de cada filtro, las flags aplicables y el comportamiento con valores null o tipos inesperados.
