Resolvendo Problema de Escopo de Variáveis PHP

Por mais que tenhamos conhecimento de como funciona o PHP, as vezes, nos deparamos com alguns problemas que acabam com nosso dia. Realmente não há jeito melhor do que contar com a experiência de quem já passou por isso para se chegar a solução desejada. Hoje vou explicar como funciona o escopo das variáveis em PHP, e já dar algumas dicas para evitar problemas futuros.

Escopo de váriáveis é o termo usado para definir o contexto em que uma determinada variável está inserida. Por padrão, as variáveis tem o escopo no “modo” global (fora de funções e métodos). Há dois contextos:

  • Global – Como o próprio nome já diz, é global, ou seja, atige toda a programação (com algumas restrinções).
  • Local – Retringe-se ao local onde está inserida. Aplicado por padrão em funções. Não dá para se usar uma variável de uma função em outra função por exemplo.

Agora que você já tem idéia do escopo de uma variável, vamos entrar em alguns detalhes:

  1. Não se define o escopo de uma variável, o processo é automático.
  2. Você pode chamar uma variável global em um contexto local.
  3. Você não chama uma variável local em um escopo global de maneira alguma.

Os problemas:

Usar uma variável qualquer (escopo global) em uma função (escopo local)

Não vou jogar conversa fora, veja o código e o resultado:

$var = 'teste';
function testarEscopo(){
	echo $var;
}
testarEscopo(); //Resultado: "" - nada!

Como você viu/reviu mais acima, a função está chamando uma variável de escopo global em um escopo local. Só que o PHP interpreta a variável como sendo de escopo local, por isso a falta de resultados. Para resolver isso, usamos a declaração global dentro da função:

$var = 'teste';

function testarEscopo(){
	global $var; //Isso aqui vai salvar o seu dia!
	echo $var;
}
testarEscopo(); //Resultado: teste

Resumidamente é a palavra “global” seguida da variável que está no escopo global e que será usada no escopo local. Para usar mais de uma variável, faça a separação por vírgula:

global $var1, $var2, $var3...

Bom primeiro problema resolvido, agora vamos dificultar um pouco mais as coisas…

Escopo de variáveis e inclusão de arquivos

Repetindo o código anterior… sendo que agora a função estará em outro arquivo:

$var = 'teste';
include_once 'arquivo.php';

Código fonte do arquivo: arquivo.php

function testarEscopo(){
	global $var; //Isso aqui vai salvar o seu dia!
	echo $var;
}
testarEscopo(); //Resultado: teste

Até agora tudo funciona perfeitamente, vamos complicar mais! Agora teremos uma função que inclui um arquivo, que tem a função que vai chamar a variável $var e exibir o valor dela. Entendeu?

$var  = 'teste';
//zilhões de funções
$admin = false; //Por algum motivo $admin ficou como false, só um exemplo;

function checaAdmin(){
	global $admin;

	if(!$admin){
		include_once "arquivo.php";
	}
}
checaAdmin();

Código fonte do arquivo: arquivo.php

function testarEscopo(){
	global $var; //Isso aqui vai salvar o seu dia!
	echo $var;
}
testarEscopo(); //Resultado: "" - nada!

Ué, deveria funcionar não é mesmo? $var está definida como global… ESTÁ CORRETO, não deve funcionar mesmo! A grande “charáda” aqui é que a inclusão do arquivo está no escopo local (dentro de uma função), sendo assim, o que é global não passa para o arquivo incluído.

Para resolver este problema, você deve também definir a variável como global na função que inclui os arquivos, mesmo que esta função não venha a usar a variável.

function checaAdmin(){
	global $admin, $var;

	if(!$admin){
		include_once "arquivo.php";
	}
}
checaAdmin();

Código fonte do arquivo: arquivo.php

function testarEscopo(){
	global $var; //Isso aqui vai salvar o seu dia!
	echo $var;
}
testarEscopo(); //Resultado: teste

Agora você resolverá seu problema! “Um stress a menos…”. Ah sim, é para qualquer tipo de elemento, não somente variáveis, vale para objetos e arrays também…

Se você quiser aprender mais, leia a documentação sobre o escopo de váriáveis diretamente do php.net.

Bom é isso, se você tem alguma dica legal que não citei, ou quiser complementar o que disse, faça um comentário!!!

Até a próxima.

1 Comentário

  1. Gianclaudio disse:
    6 de novembro de 2010 às 22:27

    Olá, Mateus.

    Parabéns pelo artigo. Direto, claro, objetivo. Tudo o que um artigo precisa ser.

    Parabéns!

Faça um Comentário