Código completo — 23.1 Páginas com sessão
Fonte que roda. Gerado por IA. Não existe no handbook original da CodeMate.
Walkthrough: 23.1 · Baixar zip
Como rodar
bash
unzip 01-sessoes.zip
cd 01-sessoes
php -S localhost:8000README.md
markdown
# 01 — Páginas com sessão
PHP puro. Sem Composer, sem banco, sem framework.
**Gerado por IA.** Não faz parte do handbook original da CodeMate.
## O que você treina
- `session_start()` / `$_SESSION`
- Form HTML + POST
- Redirect depois do POST (PRG)
- Página que exige sessão
- `htmlspecialchars` na saída
## Como rodar
```bash
php -S localhost:8000
```
Abre http://localhost:8000
1. Preenche nome e e-mail na home
2. Envia → vai para `/perfil.php` com os dados
3. `Sair` destroi a sessão
## O que não entra (de propósito)
- Banco
- Senha / login de verdade
- CSRF token
- Frameworkindex.php
php
<?php
// Sem isto, $_SESSION não existe — mesmo com o cookie PHPSESSID no browser.
session_start();
// Flash: gravou no POST, redirecionou, leu aqui, apaga. Senão o erro gruda.
$erro = $_SESSION['erro'] ?? null;
unset($_SESSION['erro']);
$usuario = $_SESSION['usuario'] ?? null;
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Home — sessão</title>
<style>
body { font-family: sans-serif; max-width: 28rem; margin: 3rem auto; padding: 0 1rem; }
label { display: block; margin: 0.75rem 0 0.25rem; }
input { width: 100%; padding: 0.4rem; box-sizing: border-box; }
button { margin-top: 1rem; padding: 0.5rem 1rem; }
.erro { color: #b00020; }
.ok { background: #f3f3f3; padding: 0.75rem 1rem; }
</style>
</head>
<body>
<h1>Home</h1>
<p>PHP puro. O form grava na sessão. Não tem banco.</p>
<?php if ($usuario): ?>
<p class="ok">
<?php // htmlspecialchars: o nome veio do form. Sem isso, XSS. ?>
Olá, <?= htmlspecialchars($usuario['nome'], ENT_QUOTES, 'UTF-8') ?>.
<a href="/perfil.php">Ver perfil</a>
</p>
<?php endif; ?>
<?php if ($erro): ?>
<p class="erro"><?= htmlspecialchars($erro, ENT_QUOTES, 'UTF-8') ?></p>
<?php endif; ?>
<form method="post" action="/salvar.php">
<label for="nome">Nome</label>
<input id="nome" name="nome" type="text" required placeholder="João">
<label for="email">E-mail</label>
<input id="email" name="email" type="email" required placeholder="joao@email.com">
<button type="submit">Guardar na sessão</button>
</form>
</body>
</html>perfil.php
php
<?php
session_start();
// Página protegida: sem sessão, nem tenta renderizar. Volta pra home.
if (empty($_SESSION['usuario'])) {
header('Location: /index.php');
exit;
}
$usuario = $_SESSION['usuario'];
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Perfil — sessão</title>
<style>
body { font-family: sans-serif; max-width: 28rem; margin: 3rem auto; padding: 0 1rem; }
dl { background: #f3f3f3; padding: 1rem; }
dt { font-weight: 700; margin-top: 0.5rem; }
</style>
</head>
<body>
<h1>Perfil</h1>
<p>Estes dados estão na <code>$_SESSION</code>. Recarregou a página? Continuam. Fechou o servidor? Sumiram.</p>
<dl>
<dt>Nome</dt>
<dd><?= htmlspecialchars($usuario['nome'], ENT_QUOTES, 'UTF-8') ?></dd>
<dt>E-mail</dt>
<dd><?= htmlspecialchars($usuario['email'], ENT_QUOTES, 'UTF-8') ?></dd>
</dl>
<p>
<a href="/index.php">Home</a>
·
<a href="/sair.php">Sair</a>
</p>
</body>
</html>sair.php
php
<?php
session_start();
// Esvazia o array desta request.
$_SESSION = [];
// Sem apagar o cookie, o browser ainda manda o PHPSESSID velho.
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
}
// Apaga o store no servidor. O próximo session_start() nasce vazio.
session_destroy();
header('Location: /index.php');
exit;salvar.php
php
<?php
session_start();
// Este script só grava. GET aqui seria bug — 405 e para.
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
http_response_code(405);
header('Allow: POST');
exit('Só POST');
}
$nome = trim((string) ($_POST['nome'] ?? ''));
$email = trim((string) ($_POST['email'] ?? ''));
if ($nome === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$_SESSION['erro'] = 'Nome e e-mail válidos, por favor.';
header('Location: /index.php');
exit;
}
// Isto some quando o processo morre. Não é banco.
$_SESSION['usuario'] = [
'nome' => $nome,
'email' => $email,
];
// PRG: redirect depois do POST. F5 no perfil não reenvia o form.
header('Location: /perfil.php');
exit;Parte do PHP/Laravel Interview Handbook — seção gerada por IA, só neste fork.