Menu

$_GET y $_POST en PHP: leer la query string y formularios

$_GET contiene la query string de la URL (?page=2 da $_GET['page']) y $_POST contiene los campos de un formulario enviado con method="post". Aprende a leer los dos de forma segura, construir enlaces con http_build_query, comprobar $_SERVER['REQUEST_METHOD'] y elegir entre GET y POST.

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

$_GET es un array con la query string de la URL, así que article.php?id=42&lang=en da $_GET['id'] === '42' y $_GET['lang'] === 'en'. $_POST es un array con los campos de un formulario enviado con method="post". Lee los dos con un valor por defecto, $_GET['id'] ?? null, porque la clave falta siempre que falta el parámetro.

Ejecuta el bloque y luego haz clic en los enlaces: cada clic vuelve a ejecutar el script con $_GET rellenado a partir de la query string del enlace.

$_GET['lang'] es lo que diga la URL, no solo los tres enlaces que imprimiste. Cualquiera puede escribir ?lang=<script> en la barra de direcciones, y por eso el bloque busca el valor en $languages en lugar de imprimirlo, y escapa el único lugar donde sí imprime datos de la petición.

Leer un número de la query string

Todos los valores de $_GET son cadenas. Para un número de página, valida y convierte en un solo paso con filter_var() y usa un valor por defecto cuando el valor falte, no sea un número o esté fuera de rango. Recorre las páginas y luego prueba los enlaces Page 999 y Page abc.

filter_var() devuelve el entero 3 para "3" y la opción default para cualquier otra cadena, así que $page es siempre un int utilizable. La página de filter_var enumera los demás validadores.

Leer los datos de un formulario con $_POST

Un formulario con method="post" envía sus campos en el cuerpo de la petición, y PHP los pone en $_POST bajo el name de cada input. $_SERVER['REQUEST_METHOD'] te dice si la petición actual es la primera visita (GET) o un envío (POST). Rellena el formulario y pulsa Send para ver los dos casos.

Un input de texto vacío se envía igualmente, como "", así que tras un envío $_POST['title'] existe aunque el visitante no haya escrito nada. En un servidor REQUEST_METHOD siempre está definido; el ?? 'GET' solo evita avisos cuando ejecutas el archivo con php en la línea de comandos. El patrón completo para validar y volver a mostrar un formulario está en la página de formularios.

Un formulario de búsqueda con method="get"

Usa GET para un formulario cuyo resultado deba ser una URL que se pueda compartir, como un buscador. El navegador convierte los campos en una query string (?q=sort&level=beginner) y el script los lee de $_GET, exactamente igual que un enlace. Busca array o string.

Construir enlaces con http_build_query

Escribir "?q=$q&page=2" a mano falla en cuanto $q contiene un espacio, un & o un #. http_build_query() codifica cada valor por ti, y el resultado pasa por htmlspecialchars() cuando acaba en un href, porque & debe ser &amp; dentro de HTML.

parse_str() con dos argumentos es como PHP construye $_GET a partir de una query string, así que es útil para probar. Pasa siempre el segundo argumento; la antigua forma con un solo argumento, que creaba variables, se eliminó en PHP 8.

$_REQUEST y por qué evitarlo

$_REQUEST es $_GET y $_POST mezclados en un solo array. Los php.ini que trae PHP fijan request_order = "GP", así que cuando los dos contienen la misma clave, gana POST; sin ese ajuste, también se mezclan las cookies:

<?php
// POST /save.php?id=1 with a form field id=2
echo $_GET['id'];      // "1"
echo $_POST['id'];     // "2"
echo $_REQUEST['id'];  // "2"

Parece cómodo, pero oculta de dónde vino un valor. Un manejador que borra un registro según $_REQUEST['id'] se puede disparar con un simple enlace, justo lo que las acciones solo por POST están pensadas para impedir. Lee $_GET o $_POST por su nombre.

GET vs POST: cuál usar

GETPOST
Por dónde viajan los datosEn la URL: ?q=php&page=2En el cuerpo de la petición
Se leen con$_GET$_POST
Favoritos, compartir, botón atrásSíNo (el navegador pide reenviar)
LongitudLimitada por la URL (unos pocos miles de caracteres es seguro)Limitada por post_max_size (8M por defecto)
Subida de archivosNoSí, con enctype="multipart/form-data" (lee $_FILES)
Úsalo paraBúsqueda, filtros, ordenación, paginaciónInicio de sesión, registro, guardar, borrar, pagos

La regla que importa: una petición GET no debe cambiar nada. Los navegadores precargan enlaces, los rastreadores los siguen y la gente los comparte, así que un enlace ?delete=5 acabará siendo seguido por algo que no pretendía borrar. Ninguno de los dos métodos está cifrado por sí solo: HTTPS protege a los dos, y POST solo mantiene los datos fuera de la URL, del historial del navegador y de los logs del servidor.

Preguntas frecuentes

¿Cómo obtengo un parámetro de la URL en PHP?

Léelo de $_GET con un valor por defecto: para page.php?id=42, $id = $_GET['id'] ?? null; da la cadena "42". Todos los valores son cadenas (o un array con id[]=), así que conviértelo y valídalo, por ejemplo con filter_var($id, FILTER_VALIDATE_INT).

¿Cuál es la diferencia entre $_GET y $_POST?

$_GET viene de la query string de la URL, así que es visible, se puede guardar en favoritos y tiene una longitud limitada; úsalo para búsquedas, filtros y páginas. $_POST viene del cuerpo de la petición de un formulario enviado con method="post"; úsalo para todo lo que cambia datos, como guardar, comprar o iniciar sesión.

¿Cómo compruebo si existe un parámetro GET en PHP?

Usa isset($_GET['q']), que es falso cuando la clave falta o es null. Para tratar también un valor vacío (?q=) como ausente, compara el valor recortado: trim($_GET['q'] ?? '') !== ''.

¿Debo usar $_REQUEST en PHP?

Normalmente no. $_REQUEST mezcla $_GET y $_POST (y, según request_order, las cookies), así que no puedes saber de dónde vino un valor, y un enlace puede aportar un valor que esperabas de un formulario. Lee $_GET o $_POST de forma explícita.

¿Cómo compruebo si una petición es GET o POST en PHP?

Compara $_SERVER['REQUEST_METHOD']: if ($_SERVER['REQUEST_METHOD'] === 'POST') { ... }. Es más fiable que isset($_POST['submit']), que falla cuando el botón no tiene name o cuando el formulario lo envía JavaScript u otro script sin ese campo.

Ilustración de los lenguajes de programación de Coddy

Aprende a programar con Coddy

COMENZAR