+4

Uma Outra Utilidade para Sessions

criado por Rodrigo Romano Moreira em 08/04/2003 8:26am
Quando comecei a criar um chat em PHP há alguns meses atrás, me espelhei em outro existente que era escrito em ASP. Mas eu tinha um problema pois ele usava o tal arquivo global.asa, que não sabia como converter para o PHP (até agora).

O global.asa controla funções e variáveis de forma que os mesmos sejam compartilhados por todos os usuários de uma aplicação Web. É uma forma interessante de scripts de chat guardarem dados sobre usuários online, sem precisar armazenar em arquivos ou banco de dados, de forma que essas variáveis e funções só existam enquanto houver pessoas logadas.

Estudando o manual do PHP.net encontrei uma maneira simples de simular o arquivo global.asa em PHP, utilizando classes e sessions.

Quando você inicializa uma sessão na forma tradicional, o PHP cria um arquivo num diretório temporário, de nomes sess_xxxxxxx. A parte representada por xxxxxxx é aleatória e pode ser da seguinte forma sess_f5e4a51ad3a9619d45214fe944c6f. Essa parte aleatória é conhecida por ID, é pode ser vista através da variável “PHPSESSID”. Exemplo:

<?php
session_start():
echo $PHPSESSID;
?>

Esse arquivo deixa de ser utilizado assim que o usuário fecha o browser (termina a session). Em cada nova iteração é gerado um novo arquivo como ID aleatório.

Para você nomear um ID, é necessário utilizar a função session_id(). Exemplo:

<?php
session_id(“romano”);
session_start();
echo $PHPSESSID;
?>

No exemplo acima, a sessão tem o nome de “romano”, e foi criado um arquivo chamado sess_romano. Uma outra característica das sessions do PHP é que os arquivos criados não são destruídos assim que se encerra a conexão. Mas se você souber o ID do arquivo, você poderá reutilizá-lo, usando a estrutura acima.

Se você criar um script que use a função session_id() você estará compartilhando as mesmas variáveis com seus usuários. O PHP tem cinco tipos de variáveis: inteiro, ponto flutuante, string, array e objeto. Todas elas podem ser armazenadas numa session.

Para exemplificar criei um script que informa os usuários on-line no momento. Não usa arquivos ou banco de dados. O script em questão fica enxuto, dê uma olhada em on-line.php:

<?php
/*
  Classe criada por Rodrigo Romano Moreira, um pequeno exemplo de como simular
  o global.asa (ASP) em PHP, utilizando sessions e classe.
  Para executar o script na sua página, basta criar um javascript:
  <script src="online.php"></script>
  O que está no atributo 'src=' deve ser o caminho do script em PHP. No meu caso "online.php".
*/
class users
{
    var $users; // Array que tem como índices os ips e armazema o tempo.

    /**
     * Função que adiciona novo ip ao array $users e remove todos os ips que expiraram.
     * Nesse exemplo o tempo de um minuto
     */
   function adduser($ip)
   {
      $this->users[$ip] = time(); // Cria um novo índice no array e 
                                  // com tempo que ele foi criado
      $timeout = time() - 60;
      $keys = array_keys($this->users);
      $total = 0; // Variável que armazena o número de usuários online no momento
      for ($i = 0; $i < sizeof($keys); $i++) {
         $x = $keys[$i];
         if ($this->users[$x] > $timeout) {
            $str[$x] = $this->users[$x];
            $total++;
         }
      }
      $this->users = $str;
      return $total;
   }
}
session_id("contador"); // Nome da sessão
session_start(); // Inicializa a sessão
session_register("cont"); // Cria a variavel $cont se ela não existir
if (!isset($cont)) { // Se o objeto não foi inicializado, ele é criado.
   $cont = new users;
}
$ip = getenv("REMOTE_ADDR"); // IP do usuario
echo "document.write(\"Usuarios online no momento : ";
echo $cont->adduser($ip);
echo "\");";
?>

As vantagens de utilizar esse algoritmo:

- Para scripts onde o armazenamento de informações será curto (usuários on-line ou chats), o script fica mais enxuto. É mais fácil trabalhar com variáveis do que com arquivos ou banco de dados.

- O script fica mais fácil de configurar e instalar.

As desvantagens:

- Para quem usa session para autenticação, esqueça. Lembre-se que no momento que você utiliza um algoritmo com session_id(), todos os usuários que utilizam o mesmo script terão o mesmo ID e compartilharão as mesmas variáveis. Imagina, você autentica um e libera o resto.

- Se uma pessoa má intencionada conhecer o ID de você utiliza, ela pode roubar um session. No Linux/Unix as sessions são armazenadas no diretório /tmp. Então é fácil saber o que tem o arquivo. Como exemplo, um arquivo chamado sess_contador (script do contador de usuários on-line) tem o seguinte conteúdo:

cont|O:5:"users":1:{s:5:"users";a:1:{s:9:"127.0.0.1";i:1035372271;}}

Não é difícil decifrar. Imagina você com um chat utilizando esse algoritmo e a pessoa tendo controle das mensagens. Isso pode ser resolvido, mas fica para um próximo artigo.

Rodrigo Romano Moreira

Comentários:

Mostrando 1 - 10 de 17 comentários
Po vei bem a acalhar esse script para meu chat pq ja estava cancado de ficar gravando em arquivos.
Simplificou totalmente.
Falou!
05/12/2005 9:37pm (~19 anos atrás)

Se por exemplo 100 user acessarem junto o sirte no seu script tera os 100 contados até um minuto ok?? mas se por exemplo eles permanecerem parados por 5 minuto nessa tela e não entre mais nenhum o seu script vai acusar 0??? Enfim queria saber uma forma de apagar a session no momento que o usuario fechar o navegador! tem como??
01/09/2005 11:24am (~19 anos atrás)

Podem me achar um pouco adverso ao artigo, mas não é a intensão. Mas o artigo só trata de uma simulaão parcial que é o compartilhamento de variáveis. Mas notem bem que o principal objetivo do global.asa não é esse. O compartilhamento de variáveis se dá pelo objeto application... O principal recurso do global.asa é informar quando exatamente o usuário fechou a sessão. informação crucial para segurança. Se a segurança do meu sistema depende-se de renomear uma pasta de usuário assim que ele fecha o navegador "no botão" e eu não puder fazer isso, o sistema é falho. A realidade é essa o ASP tem esse recurso e o Php não tem. Eu utilizo PHP mas peca nesse recurso importante.
24/06/2005 1:33am (~19 anos atrás)

Spider Poison disse:
ainda não consegui entender como o script reconhece quando uma pessoa saiu da URL. em que ponto do script faz a contagem dos usuários logados?
05/01/2005 8:45am (~20 anos atrás)

Seu artigo é ótimo. A idéia de simular o global.asa é genial. Funciona muito bem, ajudou-me bastante...
10/10/2003 7:41pm (~21 anos atrás)

Vai por mim ,esquece esse negocio do usuario sair do chat.
Se sair por vias normais tudo bem.Você cria um botão de sair e seu script.
Se ele fechar o navegador ,é só criar um maneira de filtrar as pessoas inoperantes no
chat.
03/05/2003 7:34am (~21 anos atrás)

Ae galera,

Muito bom este artigo, parabéns. Só gostaria de fazer um adendo qto ao uso de sessions para autenticação. A utilização de sessions para utilização em um sistema de autenticação pode ser segura, desde que usada corretamente. Por exemplo o php cria uma session pra cada usuário com um numero aleatório, onde vc poderá armazenar variaveis e valores, ou seja, se você não alterar o id de uma session vc poderá utiliza-la corretamente.

abraços
28/04/2003 3:42pm (~21 anos atrás)

Pior que tive outras ideias malucas ,vou estuda-las e coloca-las em pratica.
23/04/2003 6:39am (~21 anos atrás)

lehilton disse:
Ótima dica. Pode-se lembrar também que as variáveis das SESSIONS são gravadas da mesma forma que quando se utiliza serialize e unserialize. Assim, pode-se utilizar essas funções e salvar em um arquivo separado, mesmo sem utilizar session.

Ah, essa é uma ótima sólução para variáveis pequenas, mas ao começar a utilizar variáveis muito grandes e complexas a decodificação da string serializada fica um pouco lenta.
Muito bom artigo (e o chat muito criativo!).
Hito Chaves ;-)
19/04/2003 5:00pm (~21 anos atrás)

... disse:
Olá,

muito bem pensada a sua solução para o global.asa, isso demonstra que o PHP consegue perfeitamente se asemelhar a qualquer outra linguagem.
11/04/2003 8:07pm (~22 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)