Cuando se envía un formulario, el navegador arma una solicitud con los datos y la manda a la página indicada en action. PHP recibe esos datos y los deja listos en un arreglo asociativo: $_GET o $_POST, según el método del formulario.

Del formulario al arreglo

El viaje de un dato

%%{init: {'sequence': {'width': 200, 'noteMargin': 14, 'messageAlign': 'center'}}}%%
sequenceDiagram
    participant N as Navegador
    participant P as contacto.php
    Note over N: Usuario escribe "Ana"<br/>en name="nombre"
    N->>P: POST /contacto.php<br/>nombre=Ana&correo=ana@mail.cl
    Note over P: $_POST["nombre"] → "Ana"<br/>$_POST["correo"] → "ana@mail.cl"
    P-->>N: HTML con la respuesta
<form action="recibir.php" method="post">
  <label for="nombre">Nombre</label>
  <input id="nombre" name="nombre" type="text">
 
  <label for="edad">Edad</label>
  <input id="edad" name="edad" type="number">
 
  <button type="submit">Enviar</button>
</form>
<?php
// recibir.php
var_dump($_POST);

Si escribes “Ana” y “20” y envías, recibir.php muestra:

array(2) {
  ["nombre"]=>
  string(3) "Ana"
  ["edad"]=>
  string(2) "20"
}

Tres cosas que hay que tener claras:

  1. La clave de cada dato es el atributo name del campo, no el id ni el texto del <label>.
  2. Todo llega como texto: la edad es "20", no 20, aunque el campo sea type="number".
  3. Si un campo no tiene name, no llega.

Incorrecto: un campo sin name

<input id="correo" type="email">

El navegador no envía los campos sin name. En $_POST no habrá ninguna clave "correo", y leerla da Undefined array key "correo". Es la misma regla de la Unidad 1: sin name, el dato se pierde.

Correcto: name en cada campo, y el mismo nombre en PHP

<input id="correo" name="correo" type="email">
<?php
$correo = $_POST["correo"] ?? "";

GET y POST

method="get"method="post"
Los datos viajanEn la URL: buscar.php?q=phpEn el cuerpo de la solicitud, no se ven en la URL
Llegan en$_GET$_POST
Se puede guardar como favorito o compartirSíNo
Se usa paraPedir información: buscar, filtrar, ver un detalleEnviar información: contacto, registro, compra, login

Incorrecto: un formulario de registro con GET

registro.php?nombre=Ana&clave=secreta123

La contraseña queda en la barra de direcciones, en el historial del navegador y en los registros del servidor.

Correcto: GET para buscar, POST para enviar datos personales

Si el formulario cambia algo o envía datos personales, post. Si solo consulta, get.

¿Se envió el formulario?

Lo más común es que el formulario y el código que lo procesa estén en la misma página. La primera vez que alguien entra, la página se pide con GET y $_POST está vacío; al enviar, se pide con POST. $_SERVER["REQUEST_METHOD"] dice cuál de las dos es.

Una página, dos momentos

flowchart TD
    A["Llega una solicitud a contacto.php"] --> B{"¿REQUEST_METHOD<br/>es POST?"}
    B -->|"no: es GET<br/>(primera visita)"| C["Muestra el formulario vacío"]
    B -->|"sí: se envió"| D["Lee $_POST y procesa"]
    D --> E["Muestra el resultado<br/>o los errores"]
<?php
$enviado = $_SERVER["REQUEST_METHOD"] === "POST";
$nombre = "";
 
if ($enviado) {
    $nombre = trim($_POST["nombre"] ?? "");
}
?>
 
<?php if ($enviado): ?>
  <p>Gracias, <?= htmlspecialchars($nombre) ?>. Recibimos tu mensaje.</p>
<?php else: ?>
  <form action="contacto.php" method="post">
    <label for="nombre">Nombre</label>
    <input id="nombre" name="nombre" type="text">
    <button type="submit">Enviar</button>
  </form>
<?php endif; ?>

htmlspecialchars aparece desde ya

Todo dato del usuario que se imprime pasa por htmlspecialchars(). Por qué, está en htmlspecialchars. Por ahora: no imprimas nunca $_POST o $_GET sin ella.

Incorrecto: leer $_POST directamente

<?php
$nombre = $_POST["nombre"];

En la primera visita (GET) la clave no existe: Undefined array key "nombre".

Correcto: ?? y trim al leer

<?php
$nombre = trim($_POST["nombre"] ?? "");

?? evita el Warning si la clave no vino, y trim quita los espacios de los extremos. Es la forma de leer cualquier dato de un formulario.

Pruébalo

  • Envía un formulario por GET y mira los datos en la URL; cámbialo a POST y comprueba que desaparecen
  • Haz var_dump($_POST) en la página que recibe y revisa que todo llega como string
  • Quita el name de un campo y comprueba que su clave desaparece de $_POST
  • Haz una página que muestre el formulario en la primera visita y un saludo con el nombre después de enviarlo
  • Error provocado: lee $_POST["nombre"] sin ?? y entra a la página sin enviar el formulario

Errores comunes

SíntomaCausaSolución
Undefined array key "nombre"La página se abrió sin enviar el formulario, o el campo no tiene ese nameLee con $_POST["nombre"] ?? "" y revisa el name
$_POST está vacío al enviarEl formulario usa method="get" (o no tiene method, que es GET por defecto)method="post", o lee $_GET
Al enviar sale 404 Not FoundEl action apunta a un archivo que no existeRevisa el nombre en action
La comparación $_POST["edad"] === 20 nunca es verdadera$_POST["edad"] es el texto "20"Convierte con (int) antes de comparar

Checkpoint

Intenta responder antes de desplegar cada pregunta.