2.1 · Formularios y superglobales ($_GET, $_POST)

Nivel 2 · PHP y la Web

2.1Formularios y superglobales ($_GET, $_POST)

Objetivo: Recibir los datos de formulario vía $_GET/$_POST y tratarlos correctamente (validación y saneamiento del lado del servidor sistemáticos) — el corazón de la interacción web y la primera barrera de seguridad.
Tiempo estimado: 12 min · lectura autónoma · Si solo tienes 5 min: lee «Lo esencial en 30s» + el esquema.

Lo esencial en 30 segundos

  • GET lee, POST modifica: GET expone los datos en la URL (búsqueda, filtros, enlaces compartibles); POST los envía en el cuerpo (inscripción, conexión, datos sensibles) — nunca una contraseña por GET.
  • No confiar nunca en las entradas: todo dato recibido es potencialmente erróneo o malicioso — validación del servidor obligatoria, la validación JavaScript nunca basta.
  • Validar y luego sanear según el contexto: filter_var comprueba el formato, htmlspecialchars protege la visualización, las consultas preparadas protegen la base — una herramienta por uso.

Minicaso hilado — Riad y el formulario de inscripción en Constantine

Riad, desarrollador web en Constantine, crea el formulario de inscripción de una asociación local: nombre, correo electrónico, wilaya. Su primera versión muestra directamente lo que escribe el usuario — una prueba con un script en el campo nombre rompe la página. Reconstruye el tratamiento en tres tiempos: recuperar vía $_POST, validar del lado del servidor (campo obligatorio, correo válido con filter_var), escapar con htmlspecialchars antes de cualquier visualización. Este mismo proyecto reaparece en 2.2 (mantener al usuario conectado en sesión), 2.3 (factorizar el formulario por inclusiones) y 2.4 (validar el correo y fechar la inscripción).

Hilo conductor del nivel 2: este mismo proyecto de Riad reaparece en el curso, el esquema, el script y el reto 48h — y continúa en 2.2, 2.3 y 2.4.

1. $_GET y $_POST: dos métodos, dos usos

Una aplicación web INTERACTÚA con el usuario, sobre todo vía formularios. Cuando se envía el formulario, los datos viajan al servidor y PHP los RECUPERA gracias a las superglobales — arrays especiales disponibles en todo el código. El método GET pasa los datos en la URL (la «query string»: recherche.php?q=chaise): son VISIBLES, quedan en el historial, se pueden compartir y guardar en favoritos — ideal para LEER (búsqueda, filtro, paginación, orden), porque la petición es idempotente (recargarla no cambia nada). PHP los lee en $_GET ($_GET['q']). El método POST pasa los datos en el CUERPO de la petición (invisibles en la URL): ideal para CREAR/MODIFICAR (inscripción, conexión, pedido) y para datos sensibles o voluminosos. PHP los lee en $_POST. El formulario HTML declara el método (method='post') y el destino (action: el archivo PHP que trata). Riad lo aplica: su búsqueda de miembros va por GET (URL compartible), su inscripción va por POST. Existen otras superglobales: $_FILES (subidas, sección 2.3), $_SERVER (datos de la petición), $_SESSION/$_COOKIE (sección 2.2). A evitar: $_REQUEST, que mezcla GET y POST y carece de precisión.

2. No confiar nunca en las entradas

El reflejo fundamental del desarrollador web: no confiar NUNCA en los datos recibidos. Todo lo que viene del cliente (formulario, URL, cabecera) es potencialmente ERRÓNEO o MALICIOSO: un usuario puede desactivar JavaScript, modificar el código en su navegador o enviar peticiones forjadas directamente al servidor sin pasar nunca por tu página. La validación del lado del cliente (JavaScript) sirve a la EXPERIENCIA (respuesta inmediata, guiado) pero es evitable; la validación del lado del servidor (PHP) sirve a la SEGURIDAD y es obligatoria — es la única que controlas. Riad lo vivió: su control JavaScript «campo obligatorio» no bloqueó nada cuando un probador envió el formulario vacío con una herramienta directa. Regla: se vuelve a comprobar TODO del lado del servidor, siempre.

3. Validar, luego sanear según el contexto

El tratamiento del servidor se resume en dos gestos. Validar: comprobar que los datos tienen el formato esperado (¿campo obligatorio rellenado? ¿correo válido? ¿número positivo?) y rechazar/señalar si no — PHP ayuda con filter_var() (correo, URL, entero…). Sanear/escapar: tratar los datos según el uso que se les dé — htmlspecialchars() antes de MOSTRAR (contra el XSS, que inyecta HTML/JavaScript en tus páginas), consultas preparadas antes de llevar a la BASE (contra la inyección SQL, nivel 3). Una herramienta por contexto, nunca al revés. El formulario de Riad valida pues el correo con filter_var($email, FILTER_VALIDATE_EMAIL) y luego muestra el nombre con htmlspecialchars($nom) — sistemáticamente, sin excepción.

Error frecuente de interpretación: «Mi JavaScript ya lo comprueba todo, la validación PHP es redundante». No. El navegador pertenece al usuario, no a ti: JavaScript desactivado, código modificado vía las herramientas de desarrollo o petición forjada enviada directamente al servidor — en estos tres casos tu validación de cliente simplemente no existe. Quedarse solo con el control de cliente es dejar la puerta abierta a datos inválidos, a la corrupción de datos y a fallos (XSS, inyección SQL). La regla de Riad: cliente para la comodidad (deseable), servidor para la seguridad (imperativo) — se vuelve a comprobar todo del lado del servidor, cada vez.
Tratar un dato de formulario Recibir, validar, sanear Formulario GET (URL) oPOST (cuerpo)Recuperar $_GET / $_POST dellado del servidorValidar Formatoesperado (filter_var)Sanear htmlspecialchars,consultas preparadas
Recibir, validar, sanear
Versión en texto del esquema (SEO / lectores de pantalla / traducción): 1) El FORMULARIO de Riad envía los datos: su búsqueda va por GET (URL compartible), su inscripción por POST (cuerpo, no visible). 2) RECUPERA del lado del servidor con $_GET / $_POST — nunca $_REQUEST. 3) VALIDA: campo obligatorio, correo válido vía filter_var, si no rechaza. 4) SANEA según el uso: htmlspecialchars antes de mostrar (anti-XSS), consulta preparada antes de la base. Lección: recibir, validar, sanear — siempre del lado del servidor, porque el cliente es evitable.

🔎 Ejemplo concreto — 🔎 Ejemplo concreto — La inscripción de Riad, validada del lado del servidor

La primera barrera, como en el formulario de Riad:

$nom = trim($_POST['nom'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($nom === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
  echo 'Inscription invalide.';
} else {
  echo 'Merci ' . htmlspecialchars($nom, ENT_QUOTES, 'UTF-8') . ' !';
}

Lectura: recuperación vía $_POST, validación del formato, escape antes de mostrar.

Lección: la validación JavaScript NUNCA basta — el servidor vuelve a comprobarlo todo.

Vocabulario de la sección

Formulario / superglobales
Los formularios envían datos al servidor, que PHP recupera vía superglobales, arrays especiales disponibles en todas partes: $_GET, $_POST, $_FILES, $_SESSION…

Ejemplo sencillo: Riad lee el nombre introducido con $_POST['nom'].

Lo que no es: unas variables ordinarias limitadas a una función.

Reflejo: dato venido del cliente = superglobal + desconfianza.

$_GET vs $_POST
GET: datos en la URL, visibles y compartibles, para leer (búsqueda, filtros). POST: datos en el cuerpo, no visibles en la URL, para modificar o para datos sensibles.

Ejemplo sencillo: La búsqueda de Riad va por GET, su inscripción por POST.

Lo que no es: dos sintaxis intercambiables sin consecuencia.

Reflejo: leer = GET; modificar o sensible = POST.

No confiar nunca en las entradas
Todo dato de usuario es potencialmente erróneo o malicioso; validar y sanear siempre del lado del SERVIDOR antes de usarlo.

Ejemplo sencillo: Riad vuelve a comprobar el correo del lado del servidor incluso con un control JavaScript.

Lo que no es: un dato mostrado tal cual porque viene de su propio formulario.

Reflejo: entrada recibida = entrada sospechosa hasta su validación.

Validar
Comprobar que los datos tienen el formato esperado (obligatorio rellenado, correo válido, número correcto) y rechazar si no; filter_var() ayuda para correo, URL, entero.

Ejemplo sencillo: filter_var($email, FILTER_VALIDATE_EMAIL) acepta o rechaza la inscripción.

Lo que no es: mostrar el dato esperando que sea correcto.

Reflejo: cada campo = una regla de validación explícita.

Validación del servidor obligatoria
La validación de cliente (JavaScript) mejora la experiencia pero es evitable; la validación del servidor (PHP) es obligatoria porque es la única fiable.

Ejemplo sencillo: El probador de Riad evita el JavaScript, el PHP bloquea igualmente.

Lo que no es: un control JavaScript considerado como una protección.

Reflejo: comodidad del lado del cliente, seguridad del lado del servidor.

En la práctica — En la práctica — Recibir y tratar datos de formulario

  1. Cree un formulario HTML (method='post', action hacia un archivo PHP) y recupere los datos del lado del servidor vía $_POST['champ'].
  2. Compare GET y POST: un formulario de búsqueda por GET (datos en la URL) frente a un formulario de inscripción por POST (cuerpo, no visible).
  3. VALIDE los datos del lado del servidor: ¿campo obligatorio rellenado? ¿correo válido (filter_var)? ¿número correcto? — rechace/señale si es inválido.
  4. SANEE: escape con htmlspecialchars() antes de mostrar datos de usuario — y recuerde que la validación de cliente (JS) NUNCA basta.
Recibe los datos de formulario vía $_GET/$_POST y los trata correctamente (validación y saneamiento del lado del servidor sistemáticos) — el corazón de la interacción web y la primera barrera de seguridad.

Script listo para decir — explicar la doble validación a un colega (30 s)

«Para el formulario de inscripción, conservo el control JavaScript para la comodidad — respuesta inmediata. Pero vuelvo a comprobarlo todo en PHP: campo obligatorio, correo con filter_var y htmlspecialchars antes de mostrar. El JavaScript se evita en dos clics, el PHP es el único lugar que controlo de verdad.»

Para decir mostrando una petición forjada que evita el JavaScript pero resulta bloqueada por el PHP.

Modelo copiar-pegar — tratamiento seguro de formulario

' . htmlspecialchars($e, ENT_QUOTES, 'UTF-8') . '

'; } return; } echo '

Merci ' . htmlspecialchars($nom, ENT_QUOTES, 'UTF-8') . ' (' . htmlspecialchars($email, ENT_QUOTES, 'UTF-8') . ') !

';

Búsqueda compartible

El catálogo de Riad se filtra por GET: la URL contiene los criterios, se comparte y se guarda en favoritos.

Inscripción sensible

Nombre, correo y contraseña van por POST: nada en la URL, nada en el historial — luego HTTPS para el transporte.

Lista blanca de valores

La wilaya viene de una lista cerrada: Riad comprueba que el valor recibido pertenece a las opciones autorizadas, si no rechaza.

Formulario voluminoso

Mensaje largo, varios campos: POST acepta más datos que GET, limitado por la longitud de la URL.

Prudencia: Toda visualización de un dato de usuario sin htmlspecialchars() abre un fallo XSS: un atacante inyecta HTML o JavaScript que se ejecuta en el navegador de los visitantes (robo de sesión, desfiguración). Escape sistemáticamente cada dato mostrado, sin excepción. Esta guía da el gesto básico — para contextos sensibles, haga validar su código por un desarrollador experimentado.

✓ Buenas prácticas

  • GET para leer (búsqueda, filtro); POST para modificar o para datos sensibles.
  • Validar sistemáticamente del lado del servidor (filter_var, comprobaciones explícitas).
  • Escapar con htmlspecialchars antes de mostrar el menor dato de usuario.

✗ Errores frecuentes

  • Apoyarse en la validación JavaScript (evitable en dos clics).
  • Pasar una contraseña por GET (visible en la URL, el historial, los registros).
  • Usar $_REQUEST (mezcla GET/POST, menos preciso y menos seguro).

Puntos clave

  • Los FORMULARIOS envían datos que PHP recupera vía SUPERGLOBALES: $_GET (URL, búsquedas/filtros) y $_POST (cuerpo, formularios que modifican/datos sensibles).
  • REFLEJO FUNDAMENTAL: no confiar NUNCA en los datos de usuario (potencialmente erróneos o maliciosos) — VALIDAR y SANEAR siempre del lado del SERVIDOR antes de usar.
  • VALIDAR (formato esperado: correo, número, obligatorio — filter_var) y SANEAR/ESCAPAR según el contexto (htmlspecialchars antes de mostrar, consultas preparadas antes de la base).
  • La validación DEL LADO DEL CLIENTE (JavaScript) mejora la experiencia pero es EVITABLE; la validación DEL LADO DEL SERVIDOR (PHP) es OBLIGATORIA — es ella la que protege de verdad.

Reto 48h — aplique mañana

Tome un formulario real (el suyo o el de Riad: nombre + correo) y añada el tratamiento completo del servidor: recuperación vía $_POST, validación (obligatorio + filter_var), visualización con htmlspecialchars sistemático. Luego evite su propio JavaScript y compruebe que el PHP bloquea.

Lista de salida de la sección
  • Puedo explicar cuándo usar GET y cuándo usar POST, con un ejemplo de cada uno.
  • Sé validar del lado del servidor (obligatorio, filter_var) y escapar antes de mostrar.
  • He probado que una petición forjada no supera mi tratamiento del servidor.
Autoevaluación 1-5: ¿valido sistemáticamente del lado del servidor?¿escapo cada dato mostrado con htmlspecialchars?

Preguntas frecuentes

GET o POST: ¿cómo elegir el método correcto para un formulario?

Según la naturaleza de la acción y la sensibilidad de los datos. GET: datos añadidos a la URL (visibles, en historial, compartibles, en favoritos). POST: datos en el cuerpo (no en la URL). Regla: use GET para LEER/RECUPERAR (búsqueda, filtro, paginación, orden, enlace) — la petición es idempotente (recargable sin riesgo) y la URL compartible. Use POST para CREAR/MODIFICAR/ELIMINAR (inscripción, conexión, envío, pedido) — estas acciones no deben repetirse por accidente al recargar (el navegador avisa antes de reenviar datos POST), los datos no ensucian la URL y POST acepta más datos. Datos SENSIBLES (contraseña) → POST, nunca GET — pero POST solo no cifra nada: hace falta HTTPS para la verdadera confidencialidad (POST evita la exposición en la URL, HTTPS protege el transporte). Los formularios HTML solo soportan nativamente GET y POST; las API (sección 4-4) usan también PUT/PATCH/DELETE.

¿Por qué la validación del lado del servidor es obligatoria si ya valido del lado del cliente (JavaScript)?

Porque el cliente NO es fiable. La validación de CLIENTE (JavaScript) sirve a la EXPERIENCIA: respuesta inmediata, guiado — útil pero fácilmente EVITABLE: JavaScript desactivado (validación ignorada), código modificado vía las herramientas del navegador o petición enviada DIRECTAMENTE al servidor (herramienta o script) sin pasar nunca por su página. Nada garantiza que una petición recibida venga de su formulario. La validación de SERVIDOR (PHP) sirve a la SEGURIDAD: es el único lugar fiable, que USTED controla. Sin ella: datos corruptos, errores y FALLOS (inyección SQL, XSS). Haga ambas: cliente para la comodidad (deseable), servidor para la seguridad (imperativo) — vuelva a comprobar TODO (obligatorios, formatos, longitudes, valores autorizados) y sanee según el uso. Imagen: la validación de cliente es un cartel amable, la validación del servidor es el control real.

Comprueba tu comprensión

¿La validación del lado del cliente (JavaScript) basta para la seguridad?

Recursos adicionales (opcional, para ir más allá)

Examen del nivel 2Preguntas inéditas y más difíciles para validar tus conocimientos