PHP Superglobais
As superglobais são arrays que o PHP preenche sozinho a cada requisição: o que veio na URL, o que o formulário mandou, os cookies, os arquivos enviados, dados do servidor. "Super" porque estão disponíveis em qualquer lugar, até dentro de funções, sem global. Esta página é a consulta rápida; os valores mostrados são reais, do servidor embutido (php -S) na máquina da Ana. Para aprender com calma, veja $_GET e $_POST e $_SERVER e Outras Superglobais.
Tudo o que vem de $_GET, $_POST, $_COOKIE, $_FILES, $_REQUEST e das chaves HTTP_* de $_SERVER foi escrito pelo visitante, que pode mandar qualquer coisa. Sempre: confira se existe (??), valide (Validar Dados), escape na saída com htmlspecialchars (XSS) e use prepared statements no banco (SQL Injection).
Atalhos: Visão geral · $_GET · $_POST · $_SERVER · $_FILES · $_COOKIE · $_SESSION · $_ENV · $_REQUEST · $GLOBALS
Visão geral
| Superglobal | O que guarda | De onde vem | Aula |
|---|---|---|---|
$_GET | Os parâmetros da URL (depois do ?) | Links e formulários method="get" | $_GET e $_POST |
$_POST | Os campos de um formulário enviado por POST | Formulários method="post" | $_GET e $_POST |
$_SERVER | Dados da requisição e do servidor (método, URL, cabeçalhos…) | O servidor web (ou o terminal, no CLI) | $_SERVER |
$_FILES | Os arquivos enviados num formulário | <input type="file"> com enctype="multipart/form-data" | Upload de Arquivos |
$_COOKIE | Os cookies que o navegador mandou | Cookies criados antes com setcookie | Cookies |
$_SESSION | Dados guardados no servidor para este visitante | O seu código, depois de session_start() | Sessões |
$_ENV | Variáveis de ambiente | O sistema operacional (se variables_order tiver E) | $_SERVER |
$_REQUEST | $_GET + $_POST (+ $_COOKIE) misturados | Os três acima | $_GET e $_POST |
$GLOBALS | Todas as variáveis globais do script | O seu código | Escopo |
Todas são arrays associativos (aula): lê-se com colchetes e a chave entre aspas, e uma chave que não existe dá Warning: Undefined array key. Por isso o jeito seguro de ler é com ?? (aula):
<?php $nome = $_GET["nome"] ?? "visitante"; // se não veio, usa "visitante" echo "Olá, " . htmlspecialchars($nome);
E elas funcionam dentro de funções sem nenhuma declaração (as variáveis comuns não: veja Escopo):
<?php
function f() { echo $_GET["x"] ?? "sem x", " | ", $_SERVER["PHP_SELF"], "\n"; }
f();
$ php g4.php sem x | g4.php
$_GET
Cada par nome=valor da URL vira uma chave. Os valores são sempre texto (string), mesmo que pareçam números; colchetes no nome (cores[]) fazem o PHP montar um array.
| URL pedida | Resultado | Observação |
|---|---|---|
/tudo.php?nome=Bia&pagina=2 | ["nome" => "Bia", "pagina" => "2"] | "2" é texto: converta com (int) ou valide com filter_var. |
/tudo.php | [] (array vazio) | $_GET["nome"] daria Undefined array key "nome"; use $_GET["nome"] ?? "". |
/busca.php?q=caf%C3%A9+com+leite | ["q" => "café com leite"] | O PHP já decodifica %C3%A9 e + (espaço). Para montar URLs, use urlencode ou http_build_query. |
?cores[]=azul&cores[]=verde | ["cores" => ["azul", "verde"]] | Vira array (o mesmo vale para $_POST). Por isso confira com is_string antes de passar a funções de texto. |
/ola.php?nome=<b>Ana</b> | ["nome" => "<b>Ana</b>"] | O visitante pode mandar HTML. Com htmlspecialchars, sai <b>Ana</b> (inofensivo). |
Conferido com curl. O servidor roda num terminal; os pedidos, em outro:
$ php -S localhost:8000 [Fri Oct 16 20:51:24 2026] PHP 8.5.8 Development Server (http://localhost:8000) started
<?php $nome = $_GET["nome"] ?? "visitante"; ?> <p>Olá, <?= htmlspecialchars($nome) ?>!</p> <p>Método: <?= $_SERVER["REQUEST_METHOD"] ?></p>
$ curl -s "localhost:8000/ola.php?nome=Ana&cidade=Recife" <p>Olá, Ana!</p> <p>Método: GET</p> $ curl -s "localhost:8000/ola.php?nome=<b>Ana</b>" <p>Olá, <b>Ana</b>!</p> <p>Método: GET</p>
Experimente: a página recebe ?nome=Ana&cidade=Recife, mas só usa o nome. Leia também cidade (com ??) e acrescente o parágrafo Ana mora em Recife., escapado com htmlspecialchars.
<?php $nome = $_GET["nome"] ?? "visitante"; ?> <p>Olá, <?= htmlspecialchars($nome) ?>!</p> <p>Método: <?= $_SERVER["REQUEST_METHOD"] ?></p>
<?php $nome = $_GET["nome"] ?? "visitante"; $cidade = $_GET["cidade"] ?? "algum lugar"; ?> <p>Olá, <?= htmlspecialchars($nome) ?>!</p> <p>Método: <?= $_SERVER["REQUEST_METHOD"] ?></p> <p><?= htmlspecialchars($nome) ?> mora em <?= htmlspecialchars($cidade) ?>.</p>
$_POST
Os campos de um formulário com method="post". A chave é o name do campo. Os dados vão no corpo da requisição, não na URL (não aparecem no histórico nem no log do servidor).
<?php
header("Content-Type: text/plain; charset=utf-8");
echo "GET: "; var_dump($_GET);
echo "POST: "; var_dump($_POST);
echo "COOKIE: "; var_dump($_COOKIE);
echo "REQUEST: "; var_dump($_REQUEST);
Um pedido com tudo ao mesmo tempo: parâmetros na URL, campos de formulário (-d faz o curl enviar por POST, como um formulário) e um cookie (-b):
$ curl -s -b "tema=escuro" -d "nome=Ana&cores[]=azul&cores[]=verde" "localhost:8000/tudo.php?nome=Bia&pagina=2"
GET: array(2) {
["nome"]=>
string(3) "Bia"
["pagina"]=>
string(1) "2"
}
POST: array(2) {
["nome"]=>
string(3) "Ana"
["cores"]=>
array(2) {
[0]=>
string(4) "azul"
[1]=>
string(5) "verde"
}
}
COOKIE: array(1) {
["tema"]=>
string(6) "escuro"
}
REQUEST: array(4) {
["nome"]=>
string(3) "Ana"
["pagina"]=>
string(1) "2"
["cores"]=>
array(2) {
[0]=>
string(4) "azul"
[1]=>
string(5) "verde"
}
["tema"]=>
string(6) "escuro"
}
Repare: um mesmo pedido POST pode ter $_GET (o que está na URL) e $_POST (o corpo). E $_REQUEST misturou tudo: o nome do POST (Ana) apagou o do GET (Bia).
| Situação | O que acontece |
|---|---|
| Checkbox desmarcado | O campo não vem: use isset($_POST["aceito"]). |
<select multiple name="cores[]"> | $_POST["cores"] é um array (ou não existe, se nada foi escolhido). |
| Campo vazio | Vem como "" (texto vazio), não como null. |
Corpo em JSON (Content-Type: application/json) | $_POST fica vazio. Leia com json_decode(file_get_contents("php://input"), true). Veja Criar uma API JSON e o projeto da API. |
| Saber se o formulário foi enviado | if ($_SERVER["REQUEST_METHOD"] === "POST") |
$_SERVER
Informações sobre a requisição atual e o servidor. Os valores abaixo são os reais que o php -S da Ana entregou para este pedido (o -H do curl manda um cabeçalho, como um navegador faria):
$ curl -s "localhost:8000/server.php?busca=caneta&pagina=2" -H "Referer: http://localhost:8000/" -H "Accept-Language: pt-BR" REQUEST_METHOD => 'GET' REQUEST_URI => '/server.php?busca=caneta&pagina=2' QUERY_STRING => 'busca=caneta&pagina=2' SCRIPT_NAME => '/server.php' SCRIPT_FILENAME => '/home/ana/sg/server.php' PHP_SELF => '/server.php' PATH_INFO => NULL DOCUMENT_ROOT => '/home/ana/sg' SERVER_NAME => 'localhost' SERVER_PORT => '8000' SERVER_PROTOCOL => 'HTTP/1.1' SERVER_SOFTWARE => 'PHP/8.5.8 (Development Server)' SERVER_ADDR => NULL REMOTE_ADDR => '127.0.0.1' REMOTE_PORT => '46668' HTTP_HOST => 'localhost:8000' HTTP_USER_AGENT => 'curl/8.18.0' HTTP_ACCEPT => '*/*' HTTP_ACCEPT_LANGUAGE => 'pt-BR' HTTP_REFERER => 'http://localhost:8000/' CONTENT_TYPE => NULL CONTENT_LENGTH => NULL HTTPS => NULL REQUEST_TIME => 1792194685 REQUEST_TIME_FLOAT => 1792194685.127057
O server.php só percorre uma lista de chaves e mostra cada valor com var_export (NULL = a chave não existe neste pedido):
<?php
header("Content-Type: text/plain; charset=utf-8");
$chaves = ["REQUEST_METHOD", "REQUEST_URI", "QUERY_STRING", /* … */ "REQUEST_TIME_FLOAT"];
foreach ($chaves as $c) {
echo str_pad($c, 22), " => ", var_export($_SERVER[$c] ?? null, true), "\n";
}
As chaves principais
| Chave | Valor real (php -S) | Para que serve |
|---|---|---|
REQUEST_METHOD | 'GET'; num envio de formulário, 'POST' | Saber se o formulário foi enviado; numa API, escolher a ação (GET, POST, PUT, DELETE). |
REQUEST_URI | '/server.php?busca=caneta&pagina=2' | O caminho pedido, com a query string. Base de roteadores: parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH). |
QUERY_STRING | 'busca=caneta&pagina=2' | Só a parte depois do ? (já separada em $_GET). |
SCRIPT_NAME | '/server.php' | O caminho do script na URL. |
SCRIPT_FILENAME | '/home/ana/sg/server.php' | O caminho do arquivo no disco. |
PHP_SELF | '/server.php' | O script atual na URL, incluindo o PATH_INFO. Cuidado: veja o cenário abaixo. |
PATH_INFO | em /server.php/posts/3: '/posts/3' | O que vem depois do nome do script; usado em APIs simples. |
DOCUMENT_ROOT | '/home/ana/sg' | A pasta raiz do site (onde o php -S foi iniciado, ou a de -t). |
SERVER_NAME / SERVER_PORT | 'localhost' / '8000' | Nome e porta do servidor. |
SERVER_PROTOCOL | 'HTTP/1.1' | Versão do HTTP; útil em header($_SERVER["SERVER_PROTOCOL"] . " 404 Not Found"). |
SERVER_SOFTWARE | 'PHP/8.5.8 (Development Server)' | Que servidor está rodando (no Apache: Apache/2.4…). |
REMOTE_ADDR / REMOTE_PORT | '127.0.0.1' / '46668' | O IP (e a porta) de quem pediu. Atrás de um proxy, é o IP do proxy. |
HTTP_HOST | 'localhost:8000' | O endereço que o visitante digitou (cabeçalho Host). Vem do visitante: não confie cegamente. |
HTTP_USER_AGENT | 'curl/8.18.0' | O programa/navegador do visitante. Qualquer um pode mandar qualquer texto aqui. |
HTTP_ACCEPT | '*/*' | Que formatos o cliente aceita (text/html, application/json…). |
HTTP_ACCEPT_LANGUAGE | 'pt-BR' | Idiomas preferidos do visitante. |
HTTP_REFERER | 'http://localhost:8000/' | A página de onde o visitante veio (escrito assim mesmo, "referer", com um r). Só existe se o navegador mandar. |
HTTP_* (qualquer) | — | Todo cabeçalho vira uma chave: X-Token: abc → $_SERVER["HTTP_X_TOKEN"]. |
CONTENT_TYPE / CONTENT_LENGTH | no POST: 'application/x-www-form-urlencoded' / '17' | O formato e o tamanho do corpo. Não existem em GET. |
HTTPS | NULL (não existe) | Em servidores com HTTPS, costuma valer 'on'. |
SERVER_ADDR | NULL no php -S | O IP do servidor (o Apache e o nginx preenchem). |
REQUEST_TIME | 1792194685 | Quando o pedido chegou, em segundos desde 1970 (timestamp). date("d/m/Y H:i", $_SERVER["REQUEST_TIME"]); veja Datas. |
REQUEST_TIME_FLOAT | 1792194685.127057 | O mesmo, com microssegundos (para medir quanto a página demorou). |
Num pedido POST e num pedido com PATH_INFO, as chaves que mudam:
$ curl -s -d "nome=Ana&idade=29" localhost:8000/server.php | grep -E "METHOD|CONTENT|QUERY" REQUEST_METHOD => 'POST' QUERY_STRING => NULL CONTENT_TYPE => 'application/x-www-form-urlencoded' CONTENT_LENGTH => '17' $ curl -s "localhost:8000/server.php/posts/3" | grep -E "PATH_INFO|SCRIPT_NAME|PHP_SELF|REQUEST_URI" REQUEST_URI => '/server.php/posts/3' SCRIPT_NAME => '/server.php' PHP_SELF => '/server.php/posts/3' PATH_INFO => '/posts/3'
Todas as chaves que o php -S criou num GET simples (o Apache e o nginx criam mais):
$ curl -s localhost:8000/chaves.php | tr "\n" " " DOCUMENT_ROOT HTTP_ACCEPT HTTP_HOST HTTP_USER_AGENT PHP_SELF REMOTE_ADDR REMOTE_PORT REQUEST_METHOD REQUEST_TIME REQUEST_TIME_FLOAT REQUEST_URI SCRIPT_FILENAME SCRIPT_NAME SERVER_NAME SERVER_PORT SERVER_PROTOCOL SERVER_SOFTWARE
$_SERVER no terminal (CLI)
Rodando php arquivo.php, não há requisição: as chaves REQUEST_* e HTTP_* não existem, e aparecem outras, como argv (os argumentos) e as variáveis de ambiente (HOME, PATH…). Veja PHP na Linha de Comando.
<?php echo $_SERVER["argc"], "\n"; print_r($_SERVER["argv"]); echo $_SERVER["PHP_SELF"], " | ", $_SERVER["SCRIPT_NAME"], " | ", $_SERVER["SCRIPT_FILENAME"], "\n"; echo $_SERVER["REQUEST_METHOD"] ?? "(sem REQUEST_METHOD)", "\n"; echo PHP_SAPI, "\n";
$ php cli.php ana 29
3
Array
(
[0] => cli.php
[1] => ana
[2] => 29
)
cli.php | cli.php | cli.php
(sem REQUEST_METHOD)
cli
PHP_SAPI (uma constante, não uma superglobal) diz onde o PHP está rodando: cli no terminal, cli-server no php -S, apache2handler ou fpm-fcgi em servidores.
PHP_SELF no action do formulário
Um atalho antigo e perigoso, comum em tutoriais:
<form action="<?= $_SERVER["PHP_SELF"] ?>" method="post">
Como PHP_SELF inclui o PATH_INFO, que o visitante escreve na URL, alguém pode montar um link que injeta HTML na sua página:
$ curl -s "localhost:8000/self.php/%22%3E%3Cscript%3Ealert(1)%3C/script%3E" <form action="/self.php/"><script>alert(1)</script>" method="post">
O <script> entrou no HTML: é um ataque XSS (aula). Como consertar: para enviar o formulário à própria página, deixe o action vazio (action="") ou omita-o; se precisar do valor, escape: htmlspecialchars($_SERVER["PHP_SELF"]).
$_FILES
Os arquivos enviados por um formulário com method="post" e enctype="multipart/form-data". Cada campo <input type="file" name="foto"> vira $_FILES["foto"], um array com 6 chaves. O -F do curl envia como esse formulário:
$ curl -s -F "foto=@produtos.csv" -F "titulo=Lista" localhost:8000/upload.php
Array
(
[foto] => Array
(
[name] => produtos.csv
[full_path] => produtos.csv
[type] => application/octet-stream
[tmp_name] => /tmp/php3tfhotbf0m9h7eJjneJ
[error] => 0
[size] => 23
)
)
(O upload.php só faz print_r($_FILES). O campo de texto titulo foi para $_POST, não para $_FILES.)
| Chave | Exemplo real | O que é |
|---|---|---|
name | produtos.csv | O nome do arquivo no computador do visitante. Não use para salvar sem limpar: pode ter ../ ou nomes repetidos. |
full_path PHP 8.1+ | produtos.csv | O caminho relativo, quando o visitante envia uma pasta inteira. |
type | application/octet-stream (para um .txt: text/plain) | O tipo que o navegador disse. Não confie: confira o conteúdo com finfo/mime_content_type. |
tmp_name | /tmp/php3tfhotbf0m9h7eJjneJ | Onde o PHP guardou o arquivo, temporariamente. Ele é apagado no fim da requisição: mova com move_uploaded_file. |
error | 0 | O código de erro (tabela abaixo). Confira antes de tudo. |
size | 23 | Tamanho em bytes. |
Códigos de error
| Constante | Valor | Quando |
|---|---|---|
UPLOAD_ERR_OK | 0 | Deu certo. |
UPLOAD_ERR_INI_SIZE | 1 | Maior que upload_max_filesize do php.ini (padrão: 2M). Conferido: um arquivo de 3 MB chegou com [error] => 1, [size] => 0 e tmp_name vazio. |
UPLOAD_ERR_FORM_SIZE | 2 | Maior que o campo oculto MAX_FILE_SIZE do formulário. |
UPLOAD_ERR_PARTIAL | 3 | Chegou só um pedaço (conexão caiu). |
UPLOAD_ERR_NO_FILE | 4 | O formulário foi enviado sem escolher arquivo (todas as outras chaves vêm vazias). |
UPLOAD_ERR_NO_TMP_DIR | 6 | Falta a pasta temporária no servidor. |
UPLOAD_ERR_CANT_WRITE | 7 | Não conseguiu gravar no disco. |
UPLOAD_ERR_EXTENSION | 8 | Uma extensão do PHP interrompeu o envio. |
Outros limites do php.ini (valores padrão, conferidos com ini_get): post_max_size = 8M (se o pedido inteiro passar disso, $_POST e $_FILES chegam vazios, com o aviso Warning: PHP Request Startup: POST Content-Length of 9000312 bytes exceeds the limit of 8388608 bytes in Unknown on line 0, conferido com um envio de 9 MB) e max_file_uploads = 20.
Vários arquivos
Com name="fotos[]" (e multiple), cada chave vira um array, na mesma ordem: $_FILES["fotos"]["name"][0], $_FILES["fotos"]["size"][0]…
<?php
header("Content-Type: text/plain; charset=utf-8");
foreach ($_FILES["fotos"]["name"] as $i => $nome) {
echo $i, ": ", $nome, " (", $_FILES["fotos"]["size"][$i], " bytes, erro ", $_FILES["fotos"]["error"][$i], ")\n";
}
$ curl -s -F "fotos[]=@produtos.csv" -F "fotos[]=@notas.txt" localhost:8000/upload2.php 0: produtos.csv (23 bytes, erro 0) 1: notas.txt (8 bytes, erro 0)
O passo a passo completo (validar tipo e tamanho, gerar um nome seguro, move_uploaded_file) está na aula Upload de Arquivos.
$_COOKIE
Os cookies que o navegador mandou neste pedido (veja o exemplo com -b "tema=escuro" em $_POST). Pontos que confundem:
| Situação | O que acontece |
|---|---|
setcookie("tema", "escuro") e logo depois echo $_COOKIE["tema"] | Não aparece ainda: setcookie só pede ao navegador para guardar; ele manda de volta no próximo pedido. |
setcookie depois de um echo | Warning: Cannot modify header information - headers already sent (mensagem). Chame antes de qualquer saída. |
| Apagar um cookie | setcookie("tema", "", time() - 3600) (data no passado). |
| Confiar no valor | Nunca: o visitante pode editar seus cookies. Para dados importantes (quem está logado), use $_SESSION. |
Aula: Cookies.
$_SESSION
Dados que ficam no servidor, ligados ao visitante por um cookie (PHPSESSID) com um código aleatório. Só existe depois de session_start(), que precisa vir antes de qualquer saída.
<?php
session_start();
$_SESSION["visitas"] = ($_SESSION["visitas"] ?? 0) + 1;
header("Content-Type: text/plain; charset=utf-8");
echo "Visitas: ", $_SESSION["visitas"], "\n";
print_r($_SESSION);
No primeiro pedido, o PHP cria a sessão e manda o cookie (-i mostra os cabeçalhos):
$ curl -s -i localhost:8000/sessao.php
HTTP/1.1 200 OK
Host: localhost:8000
Date: Fri, 16 Oct 2026 23:51:41 GMT
Connection: close
X-Powered-By: PHP/8.5.8
Set-Cookie: PHPSESSID=4eb6a76472acd99cab32775c3082d5e2; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Visitas: 1
Array
(
[visitas] => 1
)
Quem devolve o cookie, como um navegador (-c guarda os cookies num arquivo, -b os manda de volta), continua a mesma sessão:
$ curl -s -c /tmp/c.txt -b /tmp/c.txt localhost:8000/sessao.php
Visitas: 1
Array
(
[visitas] => 1
)
$ curl -s -c /tmp/c.txt -b /tmp/c.txt localhost:8000/sessao.php
Visitas: 2
Array
(
[visitas] => 2
)
| Operação | Código |
|---|---|
| Iniciar (no topo de toda página que usa sessão) | session_start(); |
| Guardar / ler | $_SESSION["usuario"] = "ana"; / $_SESSION["usuario"] ?? null |
| Apagar um item | unset($_SESSION["carrinho"]); |
| Trocar o código depois do login (contra roubo de sessão) | session_regenerate_id(true); |
| Sair (logout) | $_SESSION = []; session_destroy(); |
Aulas: Sessões e o projeto Login com Sessão.
$_ENV
As variáveis de ambiente do sistema (como HOME). Se ela vem preenchida depende da opção variables_order do php.ini: só com a letra E. Sem php.ini o padrão é EGPCS (preenchida); os php.ini recomendados (php.ini-development e -production, usados pelas distribuições Linux) trazem GPCS (vazia):
<?php var_dump(count($_ENV)); var_dump(getenv("HOME"));
$ php env2.php int(14) string(9) "/home/ana" $ php -d variables_order=GPCS env2.php int(0) string(9) "/home/ana"
Use getenv("NOME"): funciona nos dois casos. Variáveis de ambiente são o lugar certo para senhas de banco e chaves de API (fora do código).
$_REQUEST
Uma mistura de $_GET, $_POST e, conforme o php.ini, $_COOKIE. Quando a mesma chave existe em mais de um, vence o que vem depois na ordem (request_order, ou variables_order se ela estiver vazia): no exemplo de $_POST, o nome do POST apagou o do GET, e o cookie tema entrou junto. Nos php.ini recomendados, request_order = "GP" (sem cookies).
Evite. Você não sabe de onde o valor veio, e um link (GET) pode se passar por um formulário (POST). Use $_GET ou $_POST, explicitamente.
$GLOBALS
Um array com todas as variáveis globais do script (as criadas fora de funções), acessível de dentro das funções:
<?php
$total = 10;
function somar5() {
$GLOBALS["total"] += 5;
}
somar5();
echo $total, "\n";
$ php g3.php 15
Desde o PHP 8.1 não dá para substituir o array inteiro:
$ cat g2.php
<?php
$GLOBALS = [];
$ php g2.php
Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax in /home/ana/sg/g2.php on line 2
Stack trace:
#0 {main}
Funções que mexem em variáveis globais são difíceis de entender e testar. Prefira passar valores por parâmetro e devolver com return (Escopo, Funções).
Missão: um pedido pelo formulário
Missão: a caixa já começa enviando o formulário (POST) com produto=Caneta e quantidade=3. Dentro do if, leia os dois campos de $_POST (com ??), converta a quantidade com (int), confira se o produto existe em $precos e mostre Total: R$ 7,50 (use number_format($total, 2, ",", ".")). Produto desconhecido: Pedido inválido.
<?php
$precos = ["Caneta" => 2.50, "Caderno" => 15.90];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// leia "produto" e "quantidade" de $_POST,
// calcule o total e mostre "Total: R$ 7,50"
}
?>
<form method="post">
<select name="produto"><option>Caneta</option><option>Caderno</option></select>
<input name="quantidade" type="number" value="1">
<button>Calcular</button>
</form>
<?php
$precos = ["Caneta" => 2.50, "Caderno" => 15.90];
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$produto = $_POST["produto"] ?? "";
$qtd = (int) ($_POST["quantidade"] ?? 0);
if (isset($precos[$produto]) && $qtd > 0) {
$total = $precos[$produto] * $qtd;
echo "<p>" . htmlspecialchars($produto) . " x $qtd</p>";
echo "<p>Total: R$ " . number_format($total, 2, ",", ".") . "</p>";
} else {
echo "<p>Pedido inválido.</p>";
}
}
?>
<form method="post">
<select name="produto"><option>Caneta</option><option>Caderno</option></select>
<input name="quantidade" type="number" value="1">
<button>Calcular</button>
</form>
A solução, conferida no laboratório:
$ curl -s -d "produto=Caneta&quantidade=3" localhost:8000/pedido-sol.php <p>Caneta x 3</p><p>Total: R$ 7,50</p><form method="post"> <select name="produto"><option>Caneta</option><option>Caderno</option></select> <input name="quantidade" type="number" value="1"> <button>Calcular</button> </form> $ curl -s -d "produto=Lápis&quantidade=3" localhost:8000/pedido-sol.php | head -1 <p>Pedido inválido.</p><form method="post">
Exercícios
1. Na URL /loja.php?id=7, qual é o tipo de $_GET["id"]?
2. Um cliente envia JSON no corpo de um POST. Onde estão os dados?
3. $_FILES["foto"]["error"] vale 4. O que houve?
4. Por que action="<?= $_SERVER["PHP_SELF"] ?>" é perigoso?
Complete para saber se o formulário foi enviado:
Complete para ler uma variável de ambiente de um jeito que funciona com qualquer variables_order:
Resumo
$_GET(URL),$_POST(corpo do formulário),$_COOKIE,$_FILES: vêm do visitante. Leia com??, valide, escape comhtmlspecialchars.- Valores de
$_GET/$_POSTsão sempre texto (ou array, com[]no nome). $_SERVER["REQUEST_METHOD"],["REQUEST_URI"],["HTTP_…"]são as chaves mais usadas; no terminal,["argv"].$_FILES["campo"]:name,full_path,type,tmp_name,error,size. Confiraerror === UPLOAD_ERR_OK.$_SESSIONfica no servidor (depois desession_start());$_COOKIEfica no navegador.- Prefira
getenva$_ENV; evite$_REQUESTe$GLOBALS.