Sessões
1Apresentação
O sistema de sessões permite o armazenamento temporário de variáveis, vinculadas a um visitante. A vantagem é poder
realizar processamentos em um controlador com base no processamento realizado anteriormente nos controladores executados antes dele.
Cada sessão é vinculada a um navegador por meio de um cookie definido no primeiro acesso. Isso é transparente, pois é gerenciado pelo framework.
O objeto de gerenciamento de sessão é criado automaticamente pelo Temma, se a configuração assim o previr.
2Configuração
No arquivo etc/temma.php, você pode definir como as sessões são armazenadas (veja a documentação de configuração).
Observe que, se nenhuma fonte for especificada, o Temma usa o mecanismo de sessão nativo do PHP. Note que o PHP armazena os dados de sessão em arquivos, que ficam bloqueados durante o acesso. Isso significa que apenas uma requisição pode acessá-los por vez, o que pode gerar bloqueios se você tiver requisições de longa duração (por exemplo, se você usar controladores de eventos).
3Objeto de sessão
Nos controladores, o objeto de sessão está disponível ao escrever:
$this->_session
Nos demais objetos gerenciados pelo componente de injeção de dependências, o objeto de sessão pode ser acessado ao escrever:
$this->_loader->session
4Leitura de dados
Para ler dados da sessão, basta usar o objeto como um array associativo:
$currentUser = $this->_session['user'];
Para saber se uma variável de sessão existe, ou se ela está vazia:
// a variável está definida?
if (isset($this->_session['myVariable']))
doSomething();
// a variável está vazia?
if (empty($this->_session['myOtherVariable']))
doSomethingElse();
// variável não definida: usar um valor padrão
$var = $this->_session['myVariable'] ?? 'defaultValue';
// variável não definida ou vazia: usar um valor padrão
$var = $this->_session['myVariable'] ?: 'defaultValue';
Com o método get(), você pode ler uma variável de sessão, especificando um valor padrão que é retornado caso o dado não esteja presente na sessão:
$var = $this->_session->get('myVariable', 'Default value');
É possível recuperar todas as variáveis de sessão com o método getAll():
$sessVariables = $this->_session->getAll();
$currentUser = $sessVariables['user'];
$basket = $sessVariables['basket'];
Também é possível recuperar todas as variáveis de sessão cujo nome começa com um determinado prefixo, usando o método getPrefix():
$names = $this->_session->getPrefix('name-');
foreach ($names as $nameKey => $nameValue) {
print($nameKey . ' : ' . $nameValue);
}
/*
* Por exemplo, isso pode exibir:
* name-1 : Alice
* name-2 : Bob
* name-3 : Camille
*/
print($this->_session['name-1']);
// escreve "Alice"
5Escrita de dados
Para criar ou modificar uma variável de sessão:
$this->_session['myVariable'] = $value;
Se o valor atribuído à variável for null, a variável é removida da sessão.
Para ler e escrever dados, o objeto de gerenciamento de sessão é usado como um array. Mas isso não permite
escrever valores diretamente em arrays multidimensionais.
Para modificar um array multidimensional, é preciso primeiro recuperar o array completo, modificá-lo e então
sobrescrever a variável de sessão:
// isso não funciona
$this->_session['user']['name'] = 'Einstein';
// é assim que deve ser feito
$user = $this->_session['user'];
$user['name'] = 'Einstein';
$this->_session['user'] = $user;
6Exclusão de dados
Para destruir uma variável de sessão:
unset($this->_session['myVariable']);
Para excluir todas as variáveis da sessão:
$this->_session->clean();
7Extração de dados
A extração de dados consiste em ler as variáveis de sessão e, em seguida, excluí-las da sessão.
É possível extrair dados da sessão, ou seja, lê-los e excluí-los da sessão em uma única chamada ao método extract():
$value = $this->_session->extract('myVariable');
// é equivalente a
$value = $this->_session['myVariable'];
unset($this->_session['myVariable']);
// extract() também pode receber um valor padrão
$value = $this->_session->extract('myVariable', 'default value');
Também é possível extrair todas as variáveis de sessão cujo nome começa com um determinado prefixo. As variáveis recuperadas são excluídas da sessão. Para isso, use o método extractPrefix():
$users = $this->_session->extractPrefix('user-');
foreach ($users as $login => $name) {
print("$login : $name");
}
/*
* Por exemplo, isso pode exibir:
* jrambo : John Rambo
* jconnor : John Connor
* jwick : John Wick
*/
8Variáveis flash
8.1Princípio
As variáveis flash são variáveis de sessão com um tempo de vida muito limitado. Na próxima vez que uma página é carregada, elas são extraídas (e, portanto, excluídas) da sessão, e disponibilizadas em variáveis de template.
Para transformar uma variável de sessão em uma variável flash, basta prefixar seu nome com dois sublinhados (__).
8.2Exemplo 1
Vamos imaginar um controlador Article com três ações:
- view: exibe o conteúdo de um artigo, com base no identificador passado como parâmetro. Se o artigo não existir, a ação redireciona para /article/info, tendo antes criado a variável flash __status com o valor unknown_article.
- list: exibe a lista de artigos. Se não existir nenhum item, a ação redireciona para /article/info, tendo antes criado a variável flash __status com o valor empty_list.
- info: exibe uma mensagem de erro, de acordo com o valor da variável flash __status.
Aqui está o arquivo controllers/Article.php:
<?php
/** Controlador de gerenciamento de artigos. */
class Article extends \Temma\Web\Controller {
/** Ação que exibe um artigo com base em seu identificador. */
public function view(int $articleId) {
// recupera o artigo
$article = ...
// verifica o artigo
if (!$article) {
// cria a variável flash
$this->_session['__status'] = 'unknown_article';
// redireciona
return $this->_redirect('/article/info');
}
}
/** Ação que exibe a lista de artigos. */
public function list() {
// recupera os artigos
$articles = ...
// verifica os artigos
if (!$articles) {
// cria a variável flash
$this->_session['__status'] = 'empty_list';
// redireciona
return $this->_redirect('/article/info');
}
}
/** Ação que exibe as informações. */
public function info() {
// nenhum processamento
}
}
- Linha 8: recuperação do artigo pelo identificador.
-
Linhas 10 a 15: processamento quando não há artigo com esse identificador.
- Linha 12: criação da variável flash.
- Linha 14: redirecionamento.
- Linha 20: recuperação da lista de artigos.
-
Linhas 22 a 27: processamento quando não há artigos.
- Linha 24: criação da variável flash.
- Linha 26: redirecionamento.
Aqui está o arquivo templates/article/info.tpl:
<html>
<body>
<h1>Informations</h1>
{* exibe uma mensagem com base na variável flash *}
{if $__status == 'unknown_article'}
O artigo solicitado não existe.
{elseif $__status == 'empty_list'}
Não há artigos para exibir.
{else}
Ocorreu um erro.
{/if}
</body>
</html>
8.3Exemplo 2
Neste segundo exemplo, vamos evoluir o controlador Article. Quando a ação view encontra um erro (o artigo não existe), ela redireciona para a ação list, para exibir a lista de artigos.
A ação list continua redirecionando para info se não tiver itens para exibir. Por outro lado, se você foi redirecionado a partir da ação view, é o status desta última (unknown_article) que é propagado, e não aquele que indica que não há artigos (empty_list).
Aqui está o arquivo controllers/Article.php:
<?php
/** Controlador de gerenciamento de artigos. */
class Article extends \Temma\Web\Controller {
/** Ação que exibe um artigo com base em seu identificador. */
public function view(int $articleId) {
// recupera o artigo
$article = ...
// verifica o artigo
if (!$article) {
// cria a variável flash
$this->_session['__status'] = 'unknown_article';
// redireciona
return $this->_redirect('/article/info');
}
}
/** Ação que exibe a lista de artigos. */
public function list() {
// recupera os artigos
$articles = ...
// verifica os artigos
if (!$articles) {
// cria a variável flash
if ($this['__status'])
$this->_session['__status'] = $this['__status'];
else
$this->_session['__status'] = 'empty_list';
// redireciona
return $this->_redirect('/article/info');
}
}
/** Ação que exibe as informações. */
public function info() {
// nenhum processamento
}
}
Linhas 22 a 30: processamento quando não há itens.
- Linha 24: verifica se a variável de template __status existe e não está vazia. Se for o caso, uma variável flash __status foi definida na página anterior.
- Linha 25: se a variável de template __status existir e não estiver vazia, usa seu valor para criar uma nova variável flash __status.
- Linha 27: caso contrário, cria uma variável flash com o valor empty_list.
- Linha 29: redirecionamento.