Sessões em PHP são um mecanismo para persistir dados entre requisições HTTP de um mesmo usuário. Como o HTTP é um protocolo sem estado, as sessões permitem que o servidor identifique e armazene informações específicas para cada visitante, como login, preferências ou itens de carrinho de compras. Nesta aula, exploraremos desde a inicialização até a segurança das sessões.

O PHP utiliza um identificador de sessão único (normalmente armazenado em um cookie no navegador) para vincular o usuário aos dados salvos no servidor. A manipulação é feita principalmente pelas funções session_start() e pela superglobal $_SESSION. Vamos detalhar cada aspecto a seguir.

session_start

A função session_start() é o ponto de partida para qualquer trabalho com sessões. Ela deve ser chamada antes de qualquer saída HTML (ou seja, antes de qualquer echo ou print) para que os cabeçalhos HTTP possam ser enviados corretamente. Seu papel é iniciar uma nova sessão ou retomar a sessão existente baseada no identificador enviado pelo usuário (via cookie ou URL).

Exemplo de uso:

<?php
session_start(); // Inicia ou retoma a sessão
?>
<!DOCTYPE html>
<html>
<head><title>Exemplo de Sessão</title></head>
<body>
<h1>Sessão iniciada</h1>
</body>
</html>

É importante notar que se houver qualquer saída antes de session_start(), o PHP emitirá um aviso e a sessão não será configurada. Por isso, coloque-a no topo do script, antes de qualquer HTML ou espaços em branco.

$_SESSION

A superglobal $_SESSION é um array associativo que armazena os dados da sessão atual. Você pode adicionar, modificar ou remover valores como em qualquer array. Os dados são serializados e salvos no servidor (geralmente em arquivos) entre requisições.

Exemplo de armazenamento e recuperação:

<?php
session_start();
// Armazenar dados
$_SESSION['usuario'] = 'João';
$_SESSION['preferencias'] = ['tema' => 'escuro', 'idioma' => 'pt-BR'];

// Recuperar dados
echo 'Bem-vindo, ' . $_SESSION['usuario'] . '!';
?>

Para remover uma variável específica, use unset($_SESSION['chave']). Para limpar todas as variáveis de sessão, use session_unset(). E para destruir completamente a sessão, use session_destroy() (mas lembre-se de que os dados podem persistir até o próximo acesso se não forem removidos explicitamente).

Ciclo de vida

O ciclo de vida de uma sessão começa quando o usuário faz a primeira requisição que chama session_start(). O PHP gera um ID único e o envia ao navegador (geralmente via cookie chamado PHPSESSID). Esse cookie é enviado de volta nas requisições subsequentes, permitindo que o servidor identifique o usuário.

Os dados da sessão são armazenados no servidor até que a sessão seja destruída ou até que o tempo de vida expire. O tempo de vida pode ser configurado no php.ini (diretiva session.gc_maxlifetime) ou dinamicamente com session_set_cookie_params(). Por padrão, a sessão expira quando o navegador é fechado (cookie de sessão).

Exemplo de configuração de tempo de vida:

<?php
// Define que o cookie da sessão durará 1 hora (3600 segundos)
session_set_cookie_params(3600);
session_start();
?>

Quando a sessão expira ou é destruída, os dados são removidos do servidor e o cookie é invalidado. Para destruir explicitamente:

<?php
session_start();
$_SESSION = []; // Limpa as variáveis
session_destroy(); // Destroi a sessão no servidor
// Remove o cookie (opcional)
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
?>

Segurança de sessão

A segurança das sessões é crucial para evitar ataques como sequestro de sessão (session hijacking) e fixação de sessão (session fixation). Algumas práticas recomendadas incluem:

  • Usar cookies seguros e HttpOnly: Configure o cookie da sessão com as flags Secure (envio apenas por HTTPS) e HttpOnly (inacessível via JavaScript). Isso pode ser feito via session_set_cookie_params() ou no php.ini.
  • Regenerar o ID da sessão: Após o login, chame session_regenerate_id(true) para gerar um novo ID, evitando fixação de sessão.
  • Validar o IP e User-Agent (opcional): Armazenar o IP e o User-Agent do usuário na sessão e verificar a cada requisição pode dificultar o sequestro, mas cuidado com mudanças legítimas (ex.: usuários móveis).
  • Definir tempo de expiração adequado: Sessões muito longas aumentam o risco. Use session.gc_maxlifetime e session.cookie_lifetime.

Exemplo de configuração segura:

<?php
session_set_cookie_params([
'lifetime' => 3600,
'path' => '/',
'domain' => 'seudominio.com',
'secure' => true, // apenas HTTPS
'httponly' => true, // inacessível via JS
'samesite' => 'Strict' // protege contra CSRF
]);
session_start();

// Após login bem-sucedido
session_regenerate_id(true);
$_SESSION['logged_in'] = true;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; // opcional
?>

Além disso, evite passar o ID da sessão pela URL (desative session.use_trans_sid), pois isso pode expor o ID em logs ou referências.

Boas práticas e observações finais

Sempre chame session_start() no início de todas as páginas que precisam de sessão. Lembre-se de que os dados da sessão são armazenados no servidor; para grandes volumes, considere usar um armazenamento alternativo (banco de dados, Redis) configurando session.save_handler. Nunca confie cegamente nos dados da sessão; valide permissões e integridade sempre que necessário.

Referências

Exercícios

  1. Crie um script PHP que inicia uma sessão, armazena o nome do usuário e exibe uma mensagem de boas-vindas.

    ✓ Resposta:
    <?php
    session_start();
    $_SESSION['usuario'] = 'Maria';
    echo 'Bem-vinda, ' . $_SESSION['usuario'] . '!';
    ?>
  2. Implemente um contador de visitas que incrementa a cada carregamento da página e exibe o número atual.

    ✓ Resposta:
    <?php
    session_start();
    if (!isset($_SESSION['contador'])) {
    $_SESSION['contador'] = 0;
    }
    $_SESSION['contador']++;
    echo 'Você visitou esta página ' . $_SESSION['contador'] . ' vez(es).';
    ?>
  3. Escreva um script que destrua a sessão atual e remova o cookie da sessão.

    ✓ Resposta:
    <?php
    session_start();
    $_SESSION = [];
    session_destroy();
    if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
    $params["path"], $params["domain"],
    $params["secure"], $params["httponly"]
    );
    }
    ?>
  4. Configure uma sessão para expirar após 30 minutos de inatividade, usando session_set_cookie_params e verificando o timestamp da última atividade.

    ✓ Resposta:
    <?php
    session_set_cookie_params(1800); // 30 minutos
    session_start();
    if (isset($_SESSION['ultima_atividade']) && (time() - $_SESSION['ultima_atividade']) > 1800) {
    session_destroy();
    session_start();
    }
    $_SESSION['ultima_atividade'] = time();
    // Restante do código
    ?>
  5. Implemente uma proteção básica contra session fixation: após o login, regenere o ID da sessão.

    ✓ Resposta:
    <?php
    session_start();
    if ($_POST['login'] === 'admin' && $_POST['senha'] === '123') {
    session_regenerate_id(true);
    $_SESSION['logado'] = true;
    echo 'Login realizado com sucesso!';
    } else {
    echo 'Credenciais inválidas.';
    }
    ?>