PHP

Validación de Formularios en PHP: Guía Completa con filter_input() y filter_var()

12 agosto, 2026
7 lecturas
Validación de Formularios en PHP con filter_var | Guía

¿Por qué validar formularios en PHP? {#por-que-validar}

La validación de formularios es el primer escudo de seguridad de cualquier aplicación web. Sin ella, tu sitio es vulnerable a:

  • Inyección de código malicioso (XSS)

  • Spam y bots automatizados

  • Datos corruptos en tu base de datos

  • Errores de usuario que generan mala experiencia

Dato clave: PHP ofrece funciones nativas como filter_input() y filter_var() que permiten validar y sanitizar datos sin depender de librerías externas.


Diferencia entre validación y sanitización {#validacion-vs-sanitizacion}

Antes de escribir código, es fundamental entender estas dos acciones:

Table

Acción ¿Qué hace? Ejemplo práctico
Validación Comprueba si el dato cumple un formato específico Verificar que un email tenga @ y dominio válido
Sanitización Limpia el dato eliminando caracteres peligrosos Eliminar etiquetas <script> de un campo de texto

Regla de oro: Primero sanitiza, luego valida. Nunca guardes en tu base de datos datos que no hayas limpiado previamente.


Campos requeridos en PHP {#campos-requeridos}

El paso más básico es verificar que el usuario haya completado los campos obligatorios.

Ejemplo: Verificar campos vacíos

php

<?php
$errores = [];
$nombre = $email = $mensaje = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    
    // Validar campo NOMBRE
    if (empty($_POST["nombre"])) {
        $errores[] = "El campo nombre es obligatorio.";
    } else {
        $nombre = htmlspecialchars(trim($_POST["nombre"]));
    }
    
    // Validar campo EMAIL
    if (empty($_POST["email"])) {
        $errores[] = "El campo email es obligatorio.";
    } else {
        $email = trim($_POST["email"]);
    }
    
    // Validar campo MENSAJE
    if (empty($_POST["mensaje"])) {
        $errores[] = "El campo mensaje es obligatorio.";
    } else {
        $mensaje = htmlspecialchars(trim($_POST["mensaje"]));
    }
    
    // Si no hay errores, procesar los datos
    if (empty($errores)) {
        echo "¡Formulario enviado correctamente!";
        // Aquí iría el código para enviar el email o guardar en BD
    }
}
?>

Puntos clave del código:

  • Usamos empty() para detectar campos vacíos.

  • trim() elimina espacios en blanco al inicio y final.

  • htmlspecialchars() convierte caracteres especiales en entidades HTML (protección contra XSS).



Validar email con filter_var() {#validar-email}

La función filter_var() es la forma más robusta y moderna de validar direcciones de correo en PHP.

Sintaxis básica

php

$email = "usuario@ejemplo.com";

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    echo "El email es válido.";
} else {
    echo "El email no es válido.";
}

Ejemplo práctico en un formulario

php

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    
    if (empty($email)) {
        $error = "El email es obligatorio.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $error = "El formato del email no es válido.";
    } else {
        echo "Email válido: " . $email;
    }
}
?>

¿Qué hace FILTER_SANITIZE_EMAIL?

  • Elimina todos los caracteres excepto letras, números y !#$%&'*+-/=?^_{|}~@.[]`

  • Limpia espacios y caracteres no permitidos antes de validar.


Sanitizar datos con filter_input() {#sanitizar-datos}

La función filter_input() es la forma más segura de recibir datos de formularios porque accede directamente a las superglobales ($_POST, $_GET) aplicando filtros de una sola vez.

Ventajas de filter_input()

✅ No necesitas acceder directamente a $_POST["campo"]
✅ Devuelve null si el campo no existe
✅ Aplica sanitización automática
✅ Código más limpio y legible

Filtros de sanitización más comunes

php

<?php
// Recibir y sanitizar un string (elimina etiquetas HTML)
$nombre = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);

// Recibir y sanitizar un email
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);

// Recibir y sanitizar una URL
$web = filter_input(INPUT_POST, 'web', FILTER_SANITIZE_URL);

// Recibir y sanitizar un número entero
$edad = filter_input(INPUT_POST, 'edad', FILTER_VALIDATE_INT);

// Recibir y sanitizar un número decimal
$precio = filter_input(INPUT_POST, 'precio', FILTER_VALIDATE_FLOAT);
?>


Validar URLs, enteros y strings {#validar-otros-tipos}

Validar una URL

php

$url = "https://www.ejemplo.com";

if (filter_var($url, FILTER_VALIDATE_URL)) {
    echo "URL válida.";
} else {
    echo "URL no válida.";
}

Validar números enteros

php

$edad = filter_input(INPUT_POST, 'edad', FILTER_VALIDATE_INT);

if ($edad === false || $edad < 18) {
    echo "Debes ser mayor de 18 años.";
} else {
    echo "Edad válida: " . $edad;
}

⚠️ Importante: FILTER_VALIDATE_INT devuelve false si la validación falla, pero también devuelve 0 si el número es cero. Por eso debes usar comparación estricta (===).

Validar booleanos (checkbox)

php

$acepta = filter_input(INPUT_POST, 'terminos', FILTER_VALIDATE_BOOLEAN);

if ($acepta === true) {
    echo "Términos aceptados.";
} else {
    echo "Debes aceptar los términos.";
}

Ejemplo completo: Formulario de contacto seguro {#ejemplo-completo}

A continuación, un formulario de contacto profesional que aplica todas las técnicas vistas:

HTML del formulario

HTML

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Formulario de Contacto Seguro</title>
    <style>
        .error { color: #d32f2f; font-size: 0.9em; }
        .exito { color: #388e3c; background: #e8f5e9; padding: 10px; border-radius: 4px; }
        input, textarea { display: block; margin-bottom: 10px; width: 300px; padding: 8px; }
    </style>
</head>
<body>

<h2>Contáctanos</h2>

<?php if (!empty($mensaje_exito)): ?>
    <div class="exito"><?php echo $mensaje_exito; ?></div>
<?php endif; ?>

<form method="POST" action="">
    <label>Nombre completo *</label>
    <input type="text" name="nombre" value="<?php echo $nombre ?? ''; ?>">
    <?php if (!empty($errores['nombre'])): ?>
        <span class="error"><?php echo $errores['nombre']; ?></span>
    <?php endif; ?>

    <label>Correo electrónico *</label>
    <input type="email" name="email" value="<?php echo $email ?? ''; ?>">
    <?php if (!empty($errores['email'])): ?>
        <span class="error"><?php echo $errores['email']; ?></span>
    <?php endif; ?>

    <label>Sitio web (opcional)</label>
    <input type="url" name="web" value="<?php echo $web ?? ''; ?>">
    <?php if (!empty($errores['web'])): ?>
        <span class="error"><?php echo $errores['web']; ?></span>
    <?php endif; ?>

    <label>Mensaje *</label>
    <textarea name="mensaje" rows="5"><?php echo $mensaje ?? ''; ?></textarea>
    <?php if (!empty($errores['mensaje'])): ?>
        <span class="error"><?php echo $errores['mensaje']; ?></span>
    <?php endif; ?>

    <button type="submit">Enviar mensaje</button>
</form>

</body>
</html>

PHP de procesamiento

php

<?php
$errores = [];
$mensaje_exito = "";
$nombre = $email = $web = $mensaje = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    
    // 1. SANITIZAR Y VALIDAR NOMBRE
    $nombre = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
    if (empty($nombre) || strlen($nombre) < 3) {
        $errores['nombre'] = "El nombre es obligatorio y debe tener al menos 3 caracteres.";
    }
    
    // 2. SANITIZAR Y VALIDAR EMAIL
    $email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
    if (empty($email)) {
        $errores['email'] = "El email es obligatorio.";
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errores['email'] = "El formato del email no es válido.";
    }
    
    // 3. SANITIZAR Y VALIDAR URL (opcional)
    $web = filter_input(INPUT_POST, 'web', FILTER_SANITIZE_URL);
    if (!empty($web) && !filter_var($web, FILTER_VALIDATE_URL)) {
        $errores['web'] = "La URL ingresada no es válida.";
    }
    
    // 4. SANITIZAR Y VALIDAR MENSAJE
    $mensaje = filter_input(INPUT_POST, 'mensaje', FILTER_SANITIZE_SPECIAL_CHARS);
    if (empty($mensaje) || strlen($mensaje) < 10) {
        $errores['mensaje'] = "El mensaje es obligatorio y debe tener al menos 10 caracteres.";
    }
    
    // 5. PROCESAR SI NO HAY ERRORES
    if (empty($errores)) {
        // Aquí puedes enviar el email o guardar en base de datos
        $mensaje_exito = "¡Gracias! Tu mensaje ha sido enviado correctamente.";
        $nombre = $email = $web = $mensaje = ""; // Limpiar campos
    }
}
?>


Preguntas frecuentes (FAQ) {#faq}

¿Es obligatorio usar filter_input() o puedo usar $_POST directamente?

No es obligatorio, pero filter_input() es altamente recomendado porque sanitiza automáticamente y evita acceder a superglobales de forma insegura.

¿Qué diferencia hay entre FILTER_SANITIZE_STRING y FILTER_SANITIZE_SPECIAL_CHARS?

FILTER_SANITIZE_STRING fue eliminado en PHP 8.1. Usa FILTER_SANITIZE_SPECIAL_CHARS o htmlspecialchars() como alternativa moderna.

¿Cómo evito el spam en formularios de contacto?

Además de la validación, implementa:

  • Un campo honeypot (campo oculto que solo los bots llenan)

  • reCAPTCHA v3 de Google

  • Rate limiting para limitar envíos por IP

¿Puedo validar múltiples campos con un array de filtros?

Sí, con filter_input_array():

php

$filtros = [
    'nombre' => FILTER_SANITIZE_SPECIAL_CHARS,
    'email'  => FILTER_SANITIZE_EMAIL,
    'edad'   => [
        'filter' => FILTER_VALIDATE_INT,
        'options' => ['min_range' => 18, 'max_range' => 120]
    ]
];

$resultado = filter_input_array(INPUT_POST, $filtros);


Consejos Finales: Maximiza la Seguridad y el Rendimiento de Tus Formularios

Llegados a este punto, ya tienes las herramientas técnicas para validar cualquier formulario en PHP. Pero la seguridad no termina en el código. Aplica estos consejos profesionales para llevar tus formularios al siguiente nivel:

🔒 1. Nunca Confíes en el Cliente

El navegador del usuario puede ser manipulado. Un atacante puede desactivar JavaScript, modificar el HTML o enviar peticiones directamente a tu servidor. La validación en PHP es obligatoria, independientemente de que también valides con JavaScript en el frontend.

🧹 2. Sanitiza Siempre Antes de Validar

No intentes validar datos sucios. Primero elimina caracteres peligrosos con filtros de sanitización, luego verifica que el formato sea correcto. Este orden evita falsos negativos en la validación.

📧 3. Verifica el Dominio del Email

FILTER_VALIDATE_EMAIL comprueba la sintaxis, pero no garantiza que el dominio exista. Para proyectos críticos, considera:

  • Verificar el registro MX del dominio

  • Usar servicios de verificación de email como ZeroBounce o Hunter

  • Enviar un email de confirmación antes de activar cuentas

🛡️ 4. Protege Tus Formularios Contra Bots

Incluso con validación perfecta, los bots pueden saturar tu servidor. Implementa:

  • Campo honeypot: Un input oculto que los humanos no llenan, pero los bots sí

  • reCAPTCHA v3: Invisible para el usuario, efectivo contra spam automatizado

  • Límite de envíos: Restringe el número de peticiones por IP y por minuto

💾 5. Guarda Datos Limpios en tu Base de Datos

Nunca almacenes datos que no hayas sanitizado. Si usas MySQL con PDO, combina la sanitización de PHP con consultas preparadas:

php

$stmt = $pdo->prepare("INSERT INTO contactos (nombre, email) VALUES (:nombre, :email)");
$stmt->execute([
    ':nombre' => $nombre_sanitizado,
    ':email'  => $email_validado
]);

📱 6. Optimiza la Experiencia de Usuario

Un formulario seguro no tiene por qué ser frustrante. Muestra mensajes de error específicos junto a cada campo, no un mensaje genérico al final. Usa colores diferenciados (rojo para errores, verde para éxito) y mantén los datos válidos pre-rellenados para que el usuario no tenga que reescribir todo.

🚀 7. Mantente Actualizado con PHP 8

PHP evoluciona constantemente. Algunos filtros como FILTER_SANITIZE_STRING fueron eliminados en PHP 8.1. Revisa siempre la documentación oficial para usar funciones modernas y soportadas a largo plazo.

💰 8. Monetización con AdSense: Contenido que Genera Ingresos

Si tu objetivo es monetizar este tutorial con Google AdSense, recuerda:

  • Tiempo en página: Los tutoriales con ejemplos de código funcionales retienen más a los lectores. Cuanto más tiempo pase el usuario en tu artículo, más probabilidades de clicks en anuncios.

  • Palabras clave de alto CPC: Términos como "seguridad web", "desarrollo PHP profesional" y "validación de datos" atraen publicidad de empresas de software y hosting, que suelen pagar más por click.

  • Estructura para anuncios: Coloca bloques de anuncios entre secciones H2 y después de bloques de código. Estos puntos naturales de pausa en la lectura generan mayor visibilidad sin ser intrusivos.

  • Actualizaciones periódicas: Google favorece contenido fresco. Vuelve a este artículo cada 6 meses para actualizar ejemplos, agregar nuevas técnicas y mantenerlo relevante en los resultados de búsqueda.


Tutoriales Recomendados

Sigue explorando publicaciones de la misma categoría

Ver todos