Pequena utilidade para variáveis estáticas
Finalmente, depois de muitos anos, achei que tivesse encontrado uma situação em que variáveis estáticas seriam úteis para mim no PHP.
A diferença da variável estática em uma função é que ela não perde o seu valor quando a execução deixa o seu escopo. Isto é, na próxima vez que a função for executada, a variável terá o mesmo valor que tinha na execução anterior.
Nunca tinha achado muita utilidade pra isso, até porque geralmente as variáveis locais de um método realmente tinham o tempo de vida de cada execução. Quando não, fazia mais sentido utilizar uma propriedade da classe.
Até que recentemente surgiu a necessidade de executar um método que consultava o banco de dados dezenas de vezes em uma única requisição, alterando apenas o parâmetro da query.
Como consultar o banco uma única vez não era viável neste caso, um raciocínio que segui para tentar poupar um pouco o servidor foi efetuar o prepare somente 1 vez para cada query. E aí entrou a variável estática, guardando o resultado do prepare para execuções futuras, na mesma requisição.
class TrechoDaMinhaClasse {
public function consultarAlgo($id) {
static $prepare;
if ( ! $prepare ) {
$prepare = $this->db->prepare('
SELECT id, descricao, peso
FROM minhatabela
WHERE id = :0
');
}
$rs = $this->db->execute($prepare, array($id));
return new GradeCurricular($rs->fetchRow());
}
}
Dessa forma, a partir da segunda vez que o método for chamado, ele executa direto o prepared statement com o id que deve ser consultado, sem ter que fazer o prepare de novo.
Para minha surpresa, fazendo um benchmark simples hoje (meses depois de implementar com static, assumindo que seria mais rápido), percebi que poupar o prepare no Oracle não fez muita diferença. Pelo visto o Oracle percebe que é a mesma query e não prepara novamente, ou simplesmente fazer o prepare é tão simples que não faz diferença economizar.
Sendo assim, parece que a pequena utilidade que eu tinha dado a variáveis estáticas não me serviu de nada. Estou apresentando o resultado aqui porque, bem… “Negative results are still results. Even 20 thousand of them”.
Pelo visto vou ficar sem ter utilidade para variáveis estáticas. A não ser que você tenha outros relatos positivos :)




class Pedido {
protected $items;
function getItems()
{
static $loaded;
if ( ! $loaded ) {
// Carrega os items do banco
$loaded = true;
}
return $this->items;
}
}
Nesse caso não seria mais fácil checar direto if ( ! $this->items ) ?
Assim não precisa de uma flag estática pra determinar se já foi carregado, e fica até mais parecido com lazy load que se vê por aí.
Se você criasse uma classe para gerar CSS, por exemplo, existiria um método para adicionar o CSS na página. Adicionar o CSS mais de uma vez não é interessante, então você poderia utilizar uma variável estática. Quando o CSS fosse inserido, você adicionaria um valor na variável estática. Se você tentasse adicionar esse mesmo CSS novamente, isso não seria possível, já que você verificaria o valor desta variável estática.
Valeu.
Preciso ter um controle de que certas funções serão executadas somente uma única vez:
function unique($foo) {
static $counter = 0;
if($counter++ > 1) {
die(‘ops’);
}
// continue…
}
Ops, ali seria
function unique($foo) {
static $counter = 0;
if($counter++ > 0) {
die(‘ops’);
}
// continue…
}
Pra mim, mesmo que de uma forma diferente, cai no mesmo critério do porquê eu prefiro não usar singleton.
Acho que a responsabilidade de ser singleton, ou no seu caso de controlar o limite de chamadas à função, está fora do escopo da função em si, isso faz faz parte do universo do sistema e não do pequeno pedaço que a função deveria controlar.
Preferia que outra parte do código controlasse este limite e que a função agisse normalmente – até pra testar a função seria mais fácil.