PHP Filter
Aprende la extensión filter de PHP: validar vs. sanear, filter_var(), filter_input(), constantes FILTER_VALIDATE_* y FILTER_SANITIZE_*, y flags.
La extensión filter de PHP es la herramienta incorporada para verificar y limpiar datos que provienen del exterior de tu script — campos de formulario, cadenas de consulta, cookies y cabeceras HTTP. Como esos datos los controla el usuario (y a veces un atacante), nunca debes confiar en ellos directamente. Esta página explica la diferencia entre validar y sanear, las funciones principales (filter_var() y filter_input()), las constantes de filtro más utilizadas y los errores más comunes.
Validar vs. sanear
La extensión filter realiza dos tareas distintas, y confundirlas es el error más habitual:
- Validar — comprueba si un valor cumple una regla y devuelve el valor si lo hace, o
falsesi no lo hace. Nunca modifica el valor. Usa los filtrosFILTER_VALIDATE_*. - Sanear — elimina o escapa los caracteres no permitidos y devuelve la cadena limpia. Nunca indica si la entrada era "correcta". Usa los filtros
FILTER_SANITIZE_*.
Regla general: valida para decidir si aceptar la entrada, sanea para que sea seguro usarla. No son intercambiables — un correo electrónico saneado no garantiza que esté bien formado.
filter_var() — filtrar una sola variable
filter_var() es la función principal. Recibe un valor, una constante de filtro y opciones opcionales:
filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0): mixedValidar
<?php
$email = "[email protected]";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Email is valid\n";
} else {
echo "Email is invalid\n";
}
// Numbers, URLs and IPs work the same way:
var_dump(filter_var("42", FILTER_VALIDATE_INT)); // int(42)
var_dump(filter_var("not-a-number", FILTER_VALIDATE_INT)); // bool(false)
var_dump(filter_var("https://w3docs.com", FILTER_VALIDATE_URL)); // stringSalida:
Email is valid
int(42)
bool(false)
string(18) "https://w3docs.com"Atención: los filtros de validación devuelven
falseen caso de fallo, pero0y""también son falsy.filter_var("0", FILTER_VALIDATE_INT)devuelveint(0), lo que hace fallar unifsimplista. Compara con=== false, o pasaFILTER_NULL_ON_FAILUREpara que los fallos devuelvannully puedas usar!== null.
Sanear
<?php
$dirty = " john (doe)@exa<>mple.com ";
echo filter_var($dirty, FILTER_SANITIZE_EMAIL), "\n"; // [email protected]
$comment = "<script>alert(1)</script>Hi";
echo filter_var($comment, FILTER_SANITIZE_SPECIAL_CHARS), "\n";Salida:
[email protected]
<script>alert(1)</script>HiPasar opciones y flags
Muchos filtros aceptan opciones adicionales. Por ejemplo, validar un entero solo dentro de un rango:
<?php
$options = [
"options" => ["min_range" => 1, "max_range" => 120],
];
var_dump(filter_var("130", FILTER_VALIDATE_INT, $options)); // bool(false)
var_dump(filter_var("25", FILTER_VALIDATE_INT, $options)); // int(25)Salida:
bool(false)
int(25)Los flags más útiles incluyen FILTER_NULL_ON_FAILURE (devolver null en lugar de false), FILTER_FLAG_STRIP_LOW (eliminar caracteres por debajo de ASCII 32) y FILTER_FLAG_IPV6 / FILTER_FLAG_IPV4 para acotar FILTER_VALIDATE_IP.
filter_input() — filtrar datos de la petición directamente
filter_input() lee un valor directamente de una superglobal (por nombre) y lo filtra en un solo paso, de modo que nunca tocas el array crudo $_POST / $_GET:
filter_input(int $type, string $var_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixedEl parámetro $type es uno de INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER o INPUT_ENV:
<?php
// In a real form handler:
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo "Please enter a valid email.";
} elseif ($email === null) {
echo "The email field was not submitted.";
} else {
echo "Got: $email";
}Hay tres posibles resultados: un valor (válido), false (presente pero inválido) o null (el campo no existía). Para filtrar un formulario completo de una vez, consulta filter_var_array() y filter_input_array().
Constantes de filtro más comunes
| Filtro | Tipo | Propósito |
|---|---|---|
FILTER_VALIDATE_EMAIL | validar | Dirección de correo electrónico |
FILTER_VALIDATE_URL | validar | URL |
FILTER_VALIDATE_INT / FILTER_VALIDATE_FLOAT | validar | Números enteros / decimales |
FILTER_VALIDATE_IP | validar | Dirección IPv4 / IPv6 |
FILTER_VALIDATE_BOOLEAN | validar | "yes", "on", "1" → true |
FILTER_SANITIZE_EMAIL | sanear | Eliminar caracteres de correo no permitidos |
FILTER_SANITIZE_URL | sanear | Eliminar caracteres de URL no permitidos |
FILTER_SANITIZE_NUMBER_INT | sanear | Conservar dígitos y + - |
FILTER_SANITIZE_SPECIAL_CHARS | sanear | Codificar en HTML < > & " ' |
Obsoleto desde PHP 8.1:
FILTER_SANITIZE_STRING(y su aliasFILTER_SANITIZE_STRIPPED). Para escapar la salida usahtmlspecialchars(); para limpiar la entrada, utiliza preferiblemente un filtro de validación específico más el escape adecuado al contexto en el punto de uso.
¿Cuándo debo usarlo?
- Verificar un formulario de registro o contacto antes de guardar — combínalo con Validación de formularios PHP y validación de campos URL y correo electrónico.
- Confirmar que un
idde cadena de consulta es un entero positivo antes de consultar la base de datos. - Leer y confiar en valores de cookies o
$_SERVER.
El filtrado complementa, pero no reemplaza, otras defensas: usa sentencias preparadas (sentencias preparadas de PHP MySQLi) contra la inyección SQL y htmlspecialchars() al volcar datos del usuario en HTML. Para reglas basadas en patrones que la extensión filter no puede expresar, recurre a las expresiones regulares.