Sessão PHP expira em 30 minutos: 3 melhores métodos + código

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que sua sessão PHP dura mais do que deveria?

\n\n

Você já se perguntou por que, após 30 minutos de inatividade, seu site ainda lembra que você está logado? Ou, ao contrário, seus usuários reclamam que são desconectados cedo demais? Gerenciar o tempo de vida de uma sessão em PHP é uma das dores de cabeça mais comuns para desenvolvedores iniciantes (e experientes). A pergunta "How do I expire a PHP session after 30 minutes?" tem milhares de visualizações no Stack Overflow, e não é por acaso.

\n\n

Vamos entender como fazer uma sessão PHP expirar exatamente após 30 minutos. Veremos três abordagens: da simples (mas traiçoeira) à profissional. Você descobrirá por que session.gc_maxlifetime muitas vezes não funciona como esperado e como escrever um código confiável que não te deixe na mão.

\n\n

O problema: o que é "tempo de vida da sessão" na prática?

\n\n

Antes de mergulhar no código, vamos entender o básico. Uma sessão PHP não é apenas um timer rodando no navegador. É um arquivo no servidor (geralmente em /tmp/) que armazena os dados do usuário. "Expirar" a sessão significa que esse arquivo é deletado ou se torna inválido.

\n\n

Três fatores principais influenciam o tempo de vida:

\n\n
    \n
  • Cookie da sessão: o navegador armazena o ID da sessão (geralmente no cookie PHPSESSID). Esse cookie tem seu próprio tempo de vida.
  • \n
  • Arquivo da sessão no servidor: ele tem uma data de última modificação (mtime).
  • \n
  • Coletor de lixo (GC): o PHP limpa arquivos de sessão antigos periodicamente, mas não em horários fixos — ele faz isso de forma aleatória.
  • \n
\n\n

É por causa dessa arquitetura de "três níveis" que surge a confusão. Configurar apenas um parâmetro geralmente não resolve o problema.

\n\n

Método 1: Ingênuo — apenas session.gc_maxlifetime

\n\n

A maneira mais óbvia, sugerida pela documentação, é configurar session.gc_maxlifetime. Parece que essa é a resposta para a pergunta "How do I expire a PHP session after 30 minutes?". Mas não é tão simples.

\n\n
<?php\n// Iniciar a sessão\nsession_start();\n\n// Definir o tempo de vida da sessão em segundos (30 minutos = 1800 segundos)\nini_set('session.gc_maxlifetime', 1800);\n\n// Definir o tempo de vida do cookie da sessão também para 30 minutos\nsession_set_cookie_params(1800);\n\n// Acabou? Não.\n?>
\n\n

Por que isso pode não funcionar?

\n
    \n
  • O coletor de lixo (GC) é preguiçoso. Ele é executado com uma probabilidade de session.gc_probability / session.gc_divisor (padrão 1/100). Ou seja, mesmo que o arquivo da sessão tenha uma hora, ele pode não ser removido na próxima requisição se o GC não rodar.
  • \n
  • Outras aplicações. Se o servidor tiver vários sites, eles podem limpar as sessões uns dos outros, ou não limpar as suas.
  • \n
  • Cache. Em algumas hospedagens (especialmente compartilhadas), as configurações de ini_set podem ser ignoradas.
  • \n
\n\n

Veredito: Este método é o básico, mas não é uma solução mágica. Funciona apenas em condições ideais. Para produção, é preciso ir mais fundo.

\n\n

Método 2: Timer manual dentro da sessão (recomendado)

\n\n

Esta abordagem é o meio-termo ideal. Em vez de depender do coletor de lixo, nós mesmos controlamos o tempo da última atividade do usuário. Esta é a resposta mais popular no Stack Overflow sobre sessão PHP expirar em 30 minutos.

\n\n

A ideia é simples: a cada requisição, verificamos quando o usuário esteve ativo pela última vez. Se passaram mais de 30 minutos, destruímos a sessão.

\n\n
<?php\nsession_start();\n\n// Tempo de vida da sessão em segundos\n$session_lifetime = 1800; // 30 minutos\n\n// Verificar se o timestamp da última atividade está definido\nif (isset($_SESSION['LAST_ACTIVITY'])) {\n    // Calcular a diferença entre o momento atual e a última atividade\n    $inactive_time = time() - $_SESSION['LAST_ACTIVITY'];\n    \n    // Se o tempo de inatividade for maior que o permitido\n    if ($inactive_time > $session_lifetime) {\n        // Destruir a sessão\n        session_unset();\n        session_destroy();\n        \n        // Redirecionar para a página de login (opcional)\n        header('Location: login.php?timeout=1');\n        exit;\n    }\n}\n\n// Atualizar o timestamp da última atividade\n$_SESSION['LAST_ACTIVITY'] = time();\n?>
\n\n

Por que este método é melhor?

\n
    \n
  • Controle total: você decide exatamente quando a sessão expira, independentemente do GC.
  • \n
  • Previsível: funciona sempre, em qualquer servidor.
  • \n
  • Fácil de personalizar: você pode ter diferentes tempos de expiração para diferentes tipos de usuário.
  • \n
\n\n

Dica profissional: Combine este método com a configuração do session.gc_maxlifetime para garantir que os arquivos de sessão também sejam limpos do servidor.

\n\n

Método 3: Armazenamento em banco de dados (para aplicações críticas)

\n\n

Para sistemas que exigem alta segurança ou escalabilidade, armazenar sessões no banco de dados é a melhor prática. Isso permite controle granular sobre o tempo de vida e facilita o gerenciamento em múltiplos servidores.

\n\n
<?php\n// Exemplo simplificado de verificação de sessão no banco de dados\n\n// Conectar ao banco de dados (exemplo com PDO)\n$pdo = new PDO('mysql:host=localhost;dbname=sessions', 'user', 'password');\n\n// ID da sessão atual\n$session_id = session_id();\n\n// Buscar a sessão no banco de dados\n$stmt = $pdo->prepare('SELECT * FROM sessions WHERE session_id = ?');\n$stmt->execute([$session_id]);\n$session = $stmt->fetch();\n\nif ($session) {\n    // Verificar se a sessão expirou (30 minutos = 1800 segundos)\n    if (time() - strtotime($session['last_activity']) > 1800) {\n        // Excluir a sessão expirada\n        $pdo->prepare('DELETE FROM sessions WHERE session_id = ?')->execute([$session_id]);\n        \n        // Redirecionar para o login\n        header('Location: login.php?timeout=1');\n        exit;\n    }\n    \n    // Atualizar o timestamp da última atividade\n    $pdo->prepare('UPDATE sessions SET last_activity = NOW() WHERE session_id = ?')->execute([$session_id]);\n}\n?>
\n\n

Vantagens:

\n
    \n
  • Escalabilidade: perfeito para aplicações com balanceamento de carga.
  • \n
  • Segurança: você pode invalidar sessões manualmente (ex: bloquear um usuário).
  • \n
  • Persistência: as sessões sobrevivem a reinicializações do servidor.
  • \n
\n\n

Desvantagem: Requer mais código e uma consulta ao banco de dados a cada requisição.

\n\n

Conclusão: Qual método escolher?

\n\n

A escolha depende do seu projeto:

\n
    \n
  • Site simples ou blog: Método 2 (timer manual) é suficiente e fácil de implementar.
  • \n
  • Sistema de login crítico (banco, e-commerce): Método 3 (banco de dados) oferece mais segurança e controle.
  • \n
  • Protótipo ou teste: Método 1 pode servir, mas não confie cegamente.
  • \n
\n\n

Lembre-se: a pergunta "How do I expire a PHP session after 30 minutes?" tem várias respostas, mas a mais confiável é combinar o controle manual com as configurações do servidor. Teste sempre em ambiente de produção antes de implementar.

\n\n

Gostou do tutorial? Compartilhe com outros desenvolvedores e deixe seu comentário abaixo!

Blogs

Book Recommendations