Abrir sessões em PHP de forma econômica

Artigo que mostra alguns cuidados ao se abrir sessão no PHP, de forma que não sobrecarregue o servidor com dados desnecessários.

macaco pensando
Introdução

No artigo Utilizando Sessões em PHP de forma inteligente, foi apresentado o funcionamento das sessões em PHP e algumas estratégias de como fazer bom uso das sessões. Neste artigo, veremos um outro detalhe muito importante, e que não foi citado no primeiro artigo. Trata-se da abertura de sessões de forma econômica, ou seja, apenas quando necessário.

O problema das sessões do PHP

Pergunta: para utilizar sessões em PHP, é necessário chamar session_start?

Resposta: depende.

Se você está em um trecho do script que precisa armazenar algum valor em sessão, então você realmente precisa chamar session_start, para depois guardar algo em $_SESSION. Mas se você está em um trecho do script que precisa apenas ler um valor da sessão, então você não precisa necessariamente chamar session_start, já que você pode, primeiro, verificar se a sessão existe. Afinal, se a sessão não existe, então você já sabe que não vai conseguir ler nada de $_SESSION e, consequentemente, não precisa chamar session_start. Por outro lado, se você consegue identificar que a sessão existe, então você pode chamar session_start para abri-la e tentar ler o que precisava de $_SESSION.

O problema é que, se você não leva isso em consideração, sempre vai chamar session_start (seja para escrita quanto para leitura). Consequentemente, você estará abrindo a sessão em pontos que não precisava e consumindo recursos do servidor desnecessariamente. Se sua sessão está configurada para usar memcache, por exemplo, a cada chamada de session_start você estará alocando um pouco mais de memória. Se está configurada para ser guardada em arquivo, a cada chamada de session_start você estará criando um novo arquivo em disco. Então se seu site recebe milhares de visitas diárias, é importante considerar um uso econômico das sessões.

Porém, o PHP não oferece nenhum recurso nativo para checar se a sessão "existe". Então este artigo vai discutir uma estratégia de como controlar isso por sua conta.

Como saber que a sessão existe

Em um mesmo script, existem pontos em que a sessão existe e pontos em que ela não existe mais. Por exemplo:

<?php
// Neste ponto a sessao ainda nao existe

session_start(); // Criando a sessao

// Neste ponto a sessao existe e pode ser manipulada

session_destroy(); // Destruindo a sessao

// Neste ponto a sessao nao existe mais
?>

Ou seja, para determinar se ela existe, devemos considerar as funções que o script chamou. Além disso, devemos considerar, inicialmente, se o usuário informou um ID de sessão (SESSIONID) quando acessou o script. Se o usuário informou o SESSIONID (via cookie ou trans_sid), então ele provavelmente possui a sessão, mesmo que ela ainda não tenha sido aberta.

Para saber se o usuário informou um SESSIONID, você pode verificar se existe o cookie com o nome do cookie de sessão:

$existe = isset($_COOKIE[session_name()]);

Se você usa trans_sid para trafegar o ID de sessão (não é recomendado):

$existe = isset($_GET[session_name()]);

Estratégias para controlar a abertura de sessões em PHP

Com o que vimos, podemos listar algumas estratégias importantes para se abrir sessões de forma econômica:

  • Encapsular em uma classe as funções session_start e session_destroy, para conseguirmos saber, em qualquer ponto do código, se a sessão existe ou não e se ela está aberta ou não.
  • Encapsular a função session_write_close, para conseguirmos saber, em qualquer ponto do código, se a sessão foi fechada.
  • Utilizar o padrão singleton para que exista apenas uma instância da classe e, consequentemente, quando um ponto do código abrir a sessão, outro ponto do código tenha condições de saber que isso ocorreu.
  • Verificar, inicialmente, se o usuário informou um SESSIONID.
  • Utilizar um atributo para controlar se a sessão existe o não.
  • Utilizar um atributo para controlar se a sessão está aberta ou não.

Note que a sessão pode existir, mas ainda não estar aberta para uso. Portanto, é importante controlar se a sessão está aberta para uso ou não. No PHP 5.4, podemos verificar isso chamando a função session_status (checando se ela retorna PHP_SESSION_ACTIVE). Quando chamamos a função session_write_close, a sessão continua existindo, mas não está mais aberta.

Com estas ideias em mente, você tem condições de bolar como será feito o acesso à sessão de forma econômica. Uma ideia é implementar dois métodos: abrirParaLeitura e abrirParaEscrita, então usar de acordo com a necessidade. O primeiro só abriria a sessão se ela existe, a segunda abriria incondicionalmente.

Uma outra ideia é criar um método get e outro set, sendo que eles próprios controlariam a abertura da sessão, conforme a necessidade. Esta ideia eu implementei e submeti ao site PHPClasses. Em breve, estará disponível no link: Smart Session.

4 comentários

Rubens Takiguti Ribeiro (autor do blog) disse...

Olá, Frederico

Na verdade fiz uma implementação desta ideia e coloquei no site phpclasses.org. Só falta a aprovação pelo autor, então ficará disponível no link do final do artigo.

Premiere disse...

Sempre utilizei sem fazer a abertura com session_start.

Utilizo uma função criada por mim:

public function session($name, $value = null) {
if(!is_null($value)) {
$_SESSION[$name] = $value;
} else {
if(isset($_SESSION[$name])) {
return $_SESSION[$name];
} else {
return null;
}
}
}