Escopo de variáveis
O escopo de uma variável é o contexto onde foi definida.
A maioria das variáveis do PHP tem somente escopo local.
Este escopo local inclui os arquivos incluídos e requeridos. Por
exemplo:
Aqui a variável $a estará disponível
no script incluído b.inc. Entretanto, nas
funções definidas pelo usuário, um escopo local é introduzido. Qualquer
variável utilizada dentro de uma função é, por padrão, limitada ao
escopo local da função. Por exemplo:
Este script não produz nenhuma saída porque a instrução echo
refere-se a uma versão local da variável $a,
e não possui nenhum valor atribuído neste escopo. Pode-se
perceber que esta é uma pequena diferença em relação a linguagem C, em que
variáveis globais estão automaticamente disponíveis para
funções sem sobrescrever uma definição local.
Isto pode causar problemas quando inadvertidamente
modificar-se uma variável global. No PHP, as variáveis globais precisam ser
declaradas como globais dentro de uma função, se for utilizada
em uma.
A palavra-chave global
Primeiro, um exemplo de global
:
Exemplo #1 Usando global
<?php
$a = 1;
$b = 2;
function Soma()
{
global $a, $b;
$b = $a + $b;
}
Soma();
echo $b;
?>
O script acima imprimirá3
. Declarando
$a e $b globais na
função, fará com que todas as referências a essas variáveis referenciem a
versão global. Não há um limite para o número de variáveis
globais que podem ser manipuladas por uma função.
Uma segunda maneira de acessar variáveis do escopo global é utilizando
o array especial $GLOBALS definido pelo PHP. O
exemplo anterior poderia ser reescrito como:
Exemplo #2 Usando $GLOBALS no lugar de global
<?php
$a = 1;
$b = 2;
function Soma()
{
$GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}
Soma();
echo $b;
?>
O array $GLOBALS é um array associativo, sendo
o nome da variável global a chave do array e o seu conteúdo da
variável como o valor do elemento do array.
Veja que $GLOBALS existe em qualquer escopo, isto
porque $GLOBALS é uma superglobal.
Segue um exemplo demonstrando o poder das superglobais:
Exemplo #3 Exemplo demonstrando superglobals e escopos
<?php
function test_global()
{
// A maioria das variaveis pré-definidas nao sao 'super' e requerem
// 'global' para serem disponiveis para funcoes em qualquer escopo.
global $HTTP_POST_VARS;
echo $HTTP_POST_VARS['name'];
// Superglobais são disponiveis em qualquer escopo e
// nao precisam de 'global'. Superglobais existem
// desde o PHP 4.1.0, e HTTP_POST_VARS é agora
// tida como obsoleta.
echo $_POST['name'];
}
?>
Nota:
Utilizar a instrução global
fora de uma função não é
um erro. Deve ser utilizado se um arquivo for incluído dentro de uma função.
Utilizando variáveis static
Outro recurso importante do escopo de variáveis é a
variável static
. Uma variável estática existe
somente no escopo local da função, mas não perde seu valor
quando o nível de execução do programa deixa o escopo. Considere o seguinte
exemplo:
Exemplo #4 Exemplo demonstrando a necessidade de variáveis estáticas
<?php
function Teste()
{
$a = 0;
echo $a;
$a++;
}
?>
Essa função é inútil, já que cada vez que é chamada, define
$a com o valor 0
, e imprime
0
. A instrução $a++ , que aumenta o valor da
variável, não tem sentido já que assim que a função termina a
variável $a desaparece. Para fazer um função
contadora, que não perderá a conta atual,
a variável $a será declarada como estática:
Exemplo #5 Exemplo de uso de variáveis estáticas
<?php
function Teste()
{
static $a = 0;
echo $a;
$a++;
}
?>
Agora, a variável $a é inicializada apenas na primeira chamada da função
e cada vez que a função test()
for chamada, imprimirá o
valor de $a e depois o incrementará.
Variáveis estáticas fornecem uma solução para lidar com funções
recursivas. Uma função recursiva é aquela chama a si mesma. Cuidados
devem ser tomados quando escrever funções recursivas porque é
possível que ela continue na recursão indefinidamente. Deve-se assegurar
que há uma maneira adequada de terminar a recursão. A seguinte
função recursiva conta até 10, utilizando a variável
estática $count para saber quando parar:
Exemplo #6 Variáveis estáticas em funções recursivas
<?php
function Teste()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
Teste();
}
$count--;
}
?>
Nota:
Variáveis estáticas podem ser declaradas como visto nos exemplos acima.
A partir do PHP 5.6 é possível atribuir valores a essas variáveis, que são
resultados de expressões, porém não é possível usar nenhuma função, o que causará um erro de interpretação.
Exemplo #7 Declarando variáveis estáticas
<?php
function foo(){
static $int = 0; // correro
static $int = 1+2; // correto (a partir do PHP 5.6)
static $int = sqrt(121); // errado (é uma expressão)
$int++;
echo $int;
}
?>
Nota:
Declarações estáticas são resolvida em tempo de compilação.
Referencias em variáveis global
e static
A Zend Engine 1, base do PHP 4
, implementa os modificadores
static e
global
para variáveis, em termo de
referências. Por exemplo, uma variável global verdadeira,
importada dentro do escopo de uma função com a instrução global
,
na verdade, cria uma referência para a variável global. Isto pode levar a
comportamentos imprevisíveis nos seguintes casos:
O exemplo acima irá imprimir:
NULL
object(stdClass)(0) {
}
Um comportamento similar se aplica a declaração static
.
Referências não são armazenadas estaticamente:
O exemplo acima irá imprimir:
Objeto estatico: NULL
Objeto estatico: NULL
Objeto estatico: NULL
Objeto estatico: object(stdClass)(1) {
["property"]=>
int(1)
}
Este exemplo demonstra que, atribuir uma referência a uma variável
estática, fará com que ela não se lembre quando chamou a função
&get_instance_ref()
uma segunda vez.