Kodokon kodokon.com

Formularios: recibir y validar datos

Maneja los formularios como un profesional: el método HTTP correcto, una validación estricta de la entrada y una reimpresión segura.

9 min · 3 preguntas

Abrir esta lección en Kodokon

Un formulario es el primer punto de contacto entre tus usuarios y tu código PHP. El método get coloca los datos en la URL (?q=pizza): perfecto para una búsqueda o un filtro, porque la página se puede guardar en marcadores y compartir. El método post transporta los datos en el cuerpo de la petición: es el método obligatorio siempre que la petición cambia algo (creación de cuenta, pedido, eliminación) o transporta datos sensibles. PHP almacena los valores recibidos en las superglobales $_GET y $_POST.

HTML
<form action="search.php" method="get">
  <label for="q">Search</label>
  <input id="q" name="q" type="text">
  <button type="submit">Search</button>
</form>
<?php
$query = trim($_GET['q'] ?? '');

if ($query !== '') {
    echo "<p>You are searching for: " .
        htmlspecialchars($query, ENT_QUOTES) . "</p>";
}
?>
search.php: el formulario y su procesamiento en la misma página.

Regla profesional número uno: nunca confíes en los datos entrantes. Un usuario puede enviar cualquier cosa, incluidos valores falsificados creados fuera de tu formulario. La función filter_input() lee y valida un valor en un solo paso: devuelve el valor validado, false si no es válido, y null si falta el campo - tres casos que hay que distinguir en tus mensajes de error.

PHP
<?php

declare(strict_types=1);

$errors = [];

$email = filter_input(
    INPUT_POST,
    'email',
    FILTER_VALIDATE_EMAIL
);

$age = filter_input(
    INPUT_POST,
    'age',
    FILTER_VALIDATE_INT,
    ['options' => ['min_range' => 18, 'max_range' => 120]]
);

$name = trim((string) ($_POST['name'] ?? ''));

if ($name === '' || mb_strlen($name) > 50) {
    $errors[] = "Name required (50 characters max).";
}

if (!is_string($email)) {
    $errors[] = "Invalid email address.";
}

if (!is_int($age)) {
    $errors[] = "Invalid age (between 18 and 120).";
}

if ($errors === []) {
    echo "Registration valid.";
}
Validar un registro con filter_input().

Cuando la validación falla, no devuelvas un formulario vacío: vuelve a mostrar los valores que el usuario escribió (un formulario "persistente") y los mensajes de error junto a los campos afectados. Cualquier valor que se vuelva a mostrar debe pasar por htmlspecialchars(): es lo que neutraliza las etiquetas y evita la inyección de scripts.

HTML
<?php
$name = trim($_POST['name'] ?? '');
$hasError = isset($_POST['name']) && $name === '';
$safeName = htmlspecialchars($name, ENT_QUOTES);
?>
<form method="post" action="">
  <label for="name">Your name</label>
  <input id="name" name="name"
    value="<?= $safeName ?>">
  <?php if ($hasError): ?>
    <p>Name is required.</p>
  <?php endif; ?>
  <button type="submit">Submit</button>
</form>
Formulario persistente: la entrada sobrevive al error.

Prueba de conocimientos

Comprueba que has retenido los puntos clave de esta lección.

  1. ¿Qué método HTTP es apropiado para un formulario que crea una cuenta de usuario?
    • GET, para que los datos permanezcan visibles en la URL
    • POST, porque la petición cambia el estado del servidor y los datos no deben aparecer en la URL
    • Cualquiera de los dos sirve, es cuestión de estilo
  2. ¿Qué devuelve filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL) si el campo no se envió en absoluto?
    • false
    • Una cadena vacía
    • null
    • Lanza una excepción
  3. ¿Por qué pasar un valor por htmlspecialchars() antes de volver a mostrarlo en una página?
    • Para neutralizar las etiquetas HTML y evitar la inyección de scripts (vulnerabilidad XSS)
    • Para corregir automáticamente las erratas
    • Para comprimir el valor y acelerar la visualización