Sessões e sistema de login
Os cookies armazenam dados no navegador do usuário; as sessões, no servidor. Estado de login, carrinhos de compras, sinalizadores de permissão — qualquer dado que você não queira que o usuário altere deve ficar em uma sessão. Ao final desta lição, você terá criado seu primeiro sistema de login.
1. O que é uma sessão?
Uma sessão é uma área de armazenamento privada no servidor, criada para cada usuário. O navegador armazena apenas um cookie com o ID da sessão; todos os dados reais permanecem no lado do servidor:
Cookie: Session:
Only holds the Session ID Stores the actual data (username, role, cart...)
┌──────────────┐ ┌──────────────────────┐
│ PHPSESSID │ ──match──→ │ user: John │
│ abc123 │ │ login: true │
└──────────────┘ │ cart: [3 items] │
In the browser │ role: admin │
└──────────────────────┘
On the server
2. session_start() — Iniciando uma sessão
É necessário chamar session_start() antes de utilizar qualquer funcionalidade de sessão. Essa função realiza duas tarefas:
- Se o navegador enviar um cookie de ID de sessão → carregar os dados correspondentes do servidor
- Se nenhum cookie for encontrado → criar uma nova sessão, gerar um novo ID e enviar um cookie
<?php
// session_start() must come before any HTML output
session_start();
// Store data
$_SESSION['username'] = "John";
$_SESSION['login_time'] = date("Y-m-d H:i:s");
// Read data
echo "Welcome, {$_SESSION['username']}!";
echo "Logged in at: {$_SESSION['login_time']}";
?>
session_start() deve ser chamado antes de qualquer saída — seja um echo, HTML bruto ou até mesmo um espaço isolado antes da tag <?php. Caso contrário, você receberá o temido erro headers already sent. Coloque-o bem no início do seu arquivo.
3. $_SESSION — Use-o como qualquer array
<?php
session_start();
// Store any PHP data type
$_SESSION['user'] = [
'id' => 101,
'name' => 'John',
'role' => 'member'
];
$_SESSION['cart'] = [
['name' => 'PHP Tutorial', 'price' => 39.90, 'qty' => 2],
['name' => 'MySQL Basics', 'price' => 29.90, 'qty' => 1],
];
// Read
echo $_SESSION['user']['name']; // John
// Remove a single session variable
unset($_SESSION['cart']);
// Update
$_SESSION['user']['role'] = 'admin';
?>
▶ Exemplo: Um carrinho de compras baseado em sessão
<?php
session_start();
// Initialize the cart
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = [];
}
// Add an item
if (isset($_POST['add'])) {
$item = $_POST['add'];
$_SESSION['cart'][$item] = ($_SESSION['cart'][$item] ?? 0) + 1;
}
echo "<h3>Your Cart</h3>";
foreach ($_SESSION['cart'] as $item => $qty) {
echo "{$item} × {$qty}<br>";
}
?>
<form method='POST'>
<button name='add' value='PHP Tutorial'>Add PHP Tutorial</button>
<button name='add' value='MySQL Basics'>Add MySQL Basics</button>
</form>
4. Criação de um sistema de login
▶ Exemplo: Sistema completo de login
<?php
// login.php — Login System
session_start();
// Predefined test users (in a real project, these live in a database)
$users = [
'admin' => '123456',
'john' => 'password123',
];
$error = '';
// Already logged in? Redirect to profile
if (isset($_SESSION['user'])) {
header("Location: profile.php");
exit;
}
// Handle login request
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
if (isset($users[$username]) && $users[$username] === $password) {
// Credentials verified — store user in session
$_SESSION['user'] = [
'username' => $username,
'login_time' => date("Y-m-d H:i:s"),
'last_active' => time(),
];
// Redirect to profile page
header("Location: profile.php");
exit;
} else {
$error = "Invalid username or password";
}
}
?>
<h3>Login</h3>
<?php if ($error): ?>
<p style="color:red"><?= htmlspecialchars($error) ?></p>
<?php endif; ?>
<form method="POST" action="">
<p>
<label>Username:</label>
<input type="text" name="username" required>
</p>
<p>
<label>Password:</label>
<input type="password" name="password" required>
</p>
<button type="submit">Log In</button>
</form>
<p style="color:#888">Test account: admin / 123456</p>
<?php
// profile.php — Profile Page (requires login)
session_start();
// Not logged in? Redirect to login
if (!isset($_SESSION['user'])) {
header("Location: login.php");
exit;
}
$user = $_SESSION['user'];
?>
<h2>Profile</h2>
<p>Username: <?= htmlspecialchars($user['username']) ?></p>
<p>Logged in at: <?= $user['login_time'] ?></p>
<a href="logout.php">Log Out</a>
(1) Sair da conta
<?php
// logout.php
session_start();
// Option 1: Clear only the user data
unset($_SESSION['user']);
// Option 2: Wipe the entire session
session_unset(); // Clear the $_SESSION array
session_destroy(); // Delete the server-side session file
// Redirect to login
header("Location: login.php");
exit;
?>
| Operação | Função | O que faz |
|---|---|---|
| Remover um único item | unset($_SESSION['key']) |
Exclui uma chave específica |
| Limpar todas as variáveis | session_unset() |
Esvazia $_SESSION |
| Excluir arquivo de sessão | session_destroy() |
Remove os dados de sessão do lado do servidor |
| Excluir cookie | setcookie(session_name(), '', time()-3600, '/') |
Remove o cookie PHPSESSID do navegador |
session_unset() → session_destroy() → excluir o cookie PHPSESSID → redirecionar para a página de login.
5. O ciclo de vida da sessão
User visits for the first time → PHP creates a session file (e.g., sess_abc123)
↓
Data is written to $_SESSION
↓
Cookie sent: PHPSESSID=abc123 to the browser
↓
Next visit → Browser sends PHPSESSID=abc123
↓
PHP finds sess_abc123, loads data into $_SESSION
↓
... User leaves (closes browser or is idle for a long time) ...
↓
Garbage collection → Expired session files are deleted
Por padrão, as sessões expiram após 24 minutos (session.gc_maxlifetime = 1.440 segundos em php.ini). A contagem começa a partir da hora da última modificação do arquivo, e não da última atividade do usuário.
6. Configuração de segurança da sessão
<?php
// Configure before session_start()
ini_set('session.cookie_httponly', 1); // JS can't read the session cookie (XSS protection)
ini_set('session.cookie_secure', 1); // HTTPS only (required for production)
ini_set('session.cookie_samesite', 'Lax'); // CSRF mitigation
ini_set('session.use_strict_mode', 1); // Reject uninitialized session IDs
session_start();
?>
session.use_strict_mode = 1 impede que invasores forjem um ID de sessão. Se um invasor inventar um ID inexistente, o PHP o rejeita e cria uma nova sessão.
7. Cookies x Sessões: uma visão geral
| Cookie | Sessão | |
|---|---|---|
| Localização dos dados | Navegador do usuário | Servidor |
| Segurança | Baixa (o usuário pode visualizar/editar) | Alta (o usuário nunca vê os dados) |
| Capacidade | 4 KB | Ilimitada (limitada apenas pelo espaço em disco do servidor) |
| Desempenho | Enviado a cada solicitação | Sem custo de largura de banda (consulta no lado do servidor) |
| Dependência | Autônomo | Depende de cookies (para o ID da sessão) |
| Ideal para | Preferências, modo simplificado | Login, permissões, carrinhos de compras |
❓ Perguntas Frequentes
P: A sessão desaparece quando fecho o navegador? R: Os dados da sessão ainda existem no servidor (aguardando a coleta de lixo), mas o cookie PHPSESSID no navegador geralmente desaparece quando o navegador é fechado. Na próxima vez que você abrir o navegador, não haverá um ID de sessão, então o PHP cria uma sessão totalmente nova.
P: Se vários usuários fizerem login ao mesmo tempo, suas sessões interferem entre si? R: Não. Cada usuário tem sua própria sessão com um ID de sessão exclusivo.
$_SESSIONpertence sempre ao usuário atual — não há interferência entre elas.
P: As sessões funcionam se o usuário tiver desativado os cookies? R: Não por padrão, pois o ID da sessão é transmitido por meio de um cookie. É possível transmiti-lo pela URL (
PHPSESSID=abc123), mas isso é muito inseguro — o ID da sessão acaba ficando no histórico do navegador, nos favoritos e nos logs do servidor.
📖 Resumo
- Os dados da sessão ficam armazenados no servidor; apenas o ID da sessão é transmitido em um cookie
session_start()deve ser chamado antes de qualquer saída$_SESSIONfunciona como qualquer outro array associativo- Fluxo de login: validar credenciais →
$_SESSION['user'] = ...→ redirecionar - Sair:
session_unset()+session_destroy()+ redirecionar - Segurança: httponly + secure + samesite + strict_mode
- As sessões são ideais para o estado de login, carrinhos de compras e dados de permissão
📝 Exercícios
- Implemente o sistema completo de login dos exemplos acima (login.php → profile.php → logout.php).
- Adicione um recurso “Alterar senha” à página de perfil (verifique a validade em relação à matriz de usuários predefinida).
- Implementar um acesso simples baseado em funções: somente usuários com
role === 'admin'podem ver o link “Painel de Administração” na página.



