Menu

PHP $_GET e $_POST: ler query strings e dados de formulário

$_GET guarda a query string da URL (?page=2 dá $_GET['page']) e $_POST guarda os campos de um formulário enviado com method="post". Veja como ler os dois com segurança, montar links com http_build_query, verificar $_SERVER['REQUEST_METHOD'] e escolher entre GET e POST.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

O $_GET é um array da query string da URL, então article.php?id=42&lang=en dá $_GET['id'] === '42' e $_GET['lang'] === 'en'. O $_POST é um array dos campos de um formulário enviado com method="post". Leia os dois com um padrão, $_GET['id'] ?? null, porque a chave falta sempre que o parâmetro falta.

Rode o bloco e clique nos links: cada clique executa o script de novo com $_GET preenchido pela query string do link.

$_GET['lang'] é o que a URL disser, não só os três links que você imprimiu. Qualquer pessoa pode digitar ?lang=<script> na barra de endereço, e é por isso que o bloco procura o valor em $languages em vez de imprimi-lo, e escapa o único lugar em que imprime dados da requisição.

Ler um número da query string

Todo valor em $_GET é uma string. Para um número de página, valide e converta num passo com filter_var() e use um padrão quando o valor estiver ausente, não for número ou estiver fora do intervalo. Navegue pelas páginas e depois teste os links Page 999 e Page abc.

O filter_var() retorna o inteiro 3 para "3" e a opção default para qualquer outra string, então $page é sempre um int utilizável. A página sobre filter_var lista os outros validadores.

Ler dados de formulário com $_POST

Um formulário com method="post" envia os campos no corpo da requisição, e o PHP os coloca em $_POST sob o name de cada input. $_SERVER['REQUEST_METHOD'] diz se a requisição atual é a primeira visita (GET) ou um envio (POST). Preencha o formulário e clique em Send para ver os dois.

Um input de texto vazio ainda é enviado, como "", então depois de um envio $_POST['title'] existe mesmo que o visitante não tenha digitado nada. Num servidor, REQUEST_METHOD está sempre definido; o ?? 'GET' só deixa o script quieto quando você roda o arquivo com php na linha de comando. O padrão completo para validar e reexibir um formulário está na página sobre formulários.

Um formulário de busca com method="get"

Use GET para um formulário cujo resultado deve ser uma URL compartilhável, como uma caixa de busca. O navegador transforma os campos numa query string (?q=sort&level=beginner) e o script os lê de $_GET, exatamente como num link. Busque por array ou string.

Escrever "?q=$q&page=2" à mão quebra assim que $q contém um espaço, & ou #. O http_build_query() codifica cada valor para você, e o resultado passa pelo htmlspecialchars() quando vai para um href, porque & deve ser &amp; dentro do HTML.

O parse_str() com dois argumentos é como o PHP monta o $_GET a partir de uma query string, então é prático para testes. Sempre passe o segundo argumento; a forma antiga com um argumento, que criava variáveis, foi removida no PHP 8.

$_REQUEST e por que evitá-lo

O $_REQUEST é $_GET e $_POST juntos num array. Os arquivos php.ini que vêm com o PHP definem request_order = "GP", então quando os dois contêm a mesma chave, o POST vence; sem essa configuração, os cookies também entram:

<?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 prático, mas esconde de onde veio um valor. Um handler que apaga um registro com base em $_REQUEST['id'] pode ser acionado por um simples link, que é exatamente o que as ações só com POST querem impedir. Leia $_GET ou $_POST pelo nome.

GET ou POST: qual usar

GETPOST
Onde os dados trafegamNa URL: ?q=php&page=2No corpo da requisição
Leia com$_GET$_POST
Favorito, compartilhar, botão voltarSimNão (o navegador pede para reenviar)
TamanhoLimitado pela URL (alguns milhares de caracteres é seguro)Limitado pelo post_max_size (8M por padrão)
Upload de arquivosNãoSim, com enctype="multipart/form-data" (leia $_FILES)
Use paraBusca, filtros, ordenação, paginaçãoLogin, cadastro, salvar, apagar, pagamentos

A regra que importa: uma requisição GET não deve alterar nada. Navegadores fazem prefetch de links, crawlers os seguem e pessoas os compartilham, então um link ?delete=5 uma hora vai ser seguido por algo que não queria apagar. Nenhum dos dois métodos é criptografado por si só: o HTTPS protege os dois, e o POST só mantém os dados fora da URL, do histórico do navegador e dos logs do servidor.

Perguntas frequentes

Como pego um parâmetro da URL no PHP?

Leia de $_GET com um padrão: para page.php?id=42, $id = $_GET['id'] ?? null; dá a string "42". Todo valor é uma string (ou um array para id[]=), então converta e valide, por exemplo com filter_var($id, FILTER_VALIDATE_INT).

Qual a diferença entre $_GET e $_POST?

O $_GET vem da query string da URL, então é visível, pode virar favorito e tem tamanho limitado; use para buscas, filtros e páginas. O $_POST vem do corpo da requisição de um formulário enviado com method="post"; use para tudo o que altera dados, como salvar, comprar ou fazer login.

Como verifico se um parâmetro GET existe no PHP?

Use isset($_GET['q']), que é falso quando a chave não existe ou é null. Para também tratar um valor vazio (?q=) como ausente, compare o valor com trim: trim($_GET['q'] ?? '') !== ''.

Devo usar $_REQUEST no PHP?

Normalmente não. O $_REQUEST junta $_GET e $_POST (e, dependendo do request_order, os cookies), então você não sabe de onde veio um valor, e um link pode fornecer um valor que você esperava de um formulário. Leia $_GET ou $_POST explicitamente.

Como verifico se uma requisição é GET ou POST no PHP?

Compare $_SERVER['REQUEST_METHOD']: if ($_SERVER['REQUEST_METHOD'] === 'POST') { ... }. Isso é mais confiável que isset($_POST['submit']), que falha quando o botão não tem name ou quando o formulário é enviado por JavaScript ou outro script sem esse campo.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR