Nota: Esta é uma pergunta de referência para lidar com o escopo variável no PHP. Feche qualquer uma das muitas perguntas que se encaixam nesse padrão como uma duplicata deste.
O que é "escopo variável" em PHP? As variáveis de um arquivo .php estão acessíveis em outro? Por que às vezes recebo erros de "variável indefinida" ?
Respostas:
O que é "escopo variável"?
As variáveis têm um "escopo" limitado ou "locais de onde são acessíveis". Só porque você escreveu
$foo = 'bar';
uma vez em algum lugar do seu aplicativo não significa que você pode se referir$foo
de qualquer outro lugar dentro do aplicativo. A variável$foo
tem um determinado escopo dentro do qual é válida e apenas o código no mesmo escopo tem acesso à variável.Como um escopo é definido no PHP?
Muito simples: o PHP tem escopo de função . Esse é o único tipo de separador de escopo que existe no PHP. Variáveis dentro de uma função estão disponíveis apenas dentro dessa função. Variáveis fora das funções estão disponíveis em qualquer lugar fora das funções, mas não dentro de nenhuma função. Isso significa que há um escopo especial no PHP: o escopo global . Qualquer variável declarada fora de qualquer função está dentro desse escopo global.
Exemplo:
$foo
está no escopo global ,$baz
está dentro de um escopo localmyFunc
. Somente o código internomyFunc
tem acesso$baz
. Somente o código externomyFunc
tem acesso$foo
. Nenhum dos dois tem acesso ao outro:Escopo e arquivos incluídos
Os limites do arquivo não separam o escopo:
a.php
b.php
As mesmas regras se aplicam ao
include
código d e a qualquer outro código: somentefunction
s escopo separado. Para fins de escopo, você pode incluir arquivos como código de copiar e colar:c.php
No exemplo acima,
a.php
foi incluída dentromyFunc
, quaisquer variáveis dentroa.php
somente têm escopo de função local. Só porque eles parecem estar no escopo globala.php
não significa necessariamente que estão, na verdade depende do contexto em que o código é incluído / executado.E as funções dentro de funções e classes?
Toda nova
function
declaração introduz um novo escopo, é simples assim.funções (anônimas) dentro de funções
Aulas
Para que serve o escopo?
Lidar com problemas de escopo pode parecer irritante, mas o escopo variável limitado é essencial para escrever aplicativos complexos! Se todas as variáveis declaradas estivessem disponíveis em qualquer outro lugar dentro do aplicativo, você passaria por todas as variáveis sem uma maneira real de rastrear o que muda o quê. Existem apenas tantos nomes sensíveis que você pode atribuir às suas variáveis. Você provavelmente deseja usar a variável "
$name
" em mais de um local. Se você pudesse ter esse nome de variável exclusivo apenas uma vez no aplicativo, seria necessário recorrer a esquemas de nomeação realmente complicados para garantir que suas variáveis sejam únicas e que você não esteja alterando a variável errada pelo código errado.Observar:
Se não houvesse escopo, o que a função acima faria? De onde
$bar
vem? Que estado tem? É mesmo inicializado? Você tem que verificar todas as vezes? Isso não é sustentável. O que nos leva a ...Cruzando limites do escopo
O caminho certo: passando variáveis dentro e fora
A variável
$bar
está entrando explicitamente nesse escopo como argumento de função. Apenas olhando para esta função, fica claro de onde os valores com os quais trabalha se originam. Em seguida, ele retorna explicitamente um valor. O chamador tem confiança para saber com quais variáveis a função trabalhará e de onde vêm seus valores de retorno:Estendendo o escopo das variáveis para funções anônimas
A função anônima inclui explicitamente
$foo
do seu escopo circundante. Observe que isso não é o mesmo que escopo global .O caminho errado:
global
Como dito anteriormente, o escopo global é algo especial e as funções podem importar explicitamente variáveis dele:
Esta função usa e modifica a variável global
$foo
. Não faça isso! (A menos que você realmente saiba realmente o que está fazendo e, mesmo assim: não saiba!)Todo o chamador desta função vê é o seguinte:
Não há indicação de que essa função tenha efeitos colaterais , mas tem. Isso facilmente se torna uma bagunça emaranhada, pois algumas funções continuam modificando e exigindo algum estado global. Você quer que as funções sejam sem estado , agindo apenas em suas entradas e retornando saídas definidas, por mais que você as chame.
Você deve evitar usar o escopo global da maneira mais possível; certamente você não deve estar "puxando" variáveis do escopo global para um escopo local.
fonte
global
, por favor, diga-nos quando devemos usarglobal
? E por favor explique (um pouco) o que éstatic
..?global
. Está sempre errado. A passagem dos parâmetros da função está correta.static
é explicado bem no manual e não tem muito a ver com o escopo. Em poucas palavras, pode ser pensado como uma "variável global com escopo definido". Estou expandindo um pouco seu uso aqui kunststube.net/static .include_once
e possivelmenterequire_once
também deve ser adicionada em algum lugar; apenas dizendo. O OP também votou na reabertura da pergunta. O post seria um caso especial e o que deveria ser feito?Embora as variáveis definidas dentro do escopo de uma função não possam ser acessadas de fora, isso não significa que você não poderá usar seus valores depois que a função for concluída. O PHP tem uma
static
palavra - chave conhecida que é amplamente usada no PHP orientado a objetos para definir métodos e propriedades estáticas, mas é preciso ter em mente questatic
também pode ser usada dentro de funções para definir variáveis estáticas.O que é 'variável estática'?
A variável estática difere da variável comum definida no escopo da função, caso não perca valor quando a execução do programa deixa esse escopo. Vamos considerar o seguinte exemplo de uso de variáveis estáticas:
Resultado:
Se tivéssemos definido
$counter
semstatic
, cada vez que o valor ecoado seria o mesmo que o$num
parâmetro passado para a função. O usostatic
permite criar esse contador simples sem solução adicional.Casos de uso de variáveis estáticas
Truques
A variável estática existe apenas em um escopo de função local. Ele não pode ser acessado fora da função em que foi definido. Portanto, você pode ter certeza de que ele manterá seu valor inalterado até a próxima chamada para essa função.
A variável estática pode ser definida apenas como uma expressão escalar ou escalar (desde o PHP 5.6). Atribuir outros valores a ele inevitavelmente leva a uma falha pelo menos no momento em que este artigo foi escrito. No entanto, você é capaz de fazer isso apenas na próxima linha do seu código:
Resultado:
A função estática é meio 'compartilhada' entre métodos de objetos da mesma classe. É fácil entender, visualizando o seguinte exemplo:
Isso funciona apenas com objetos da mesma classe. Se os objetos forem de classes diferentes (até mesmo se estendendo), o comportamento dos vars estáticos será o esperado.
A variável estática é a única maneira de manter valores entre as chamadas para uma função?
Outra maneira de manter valores entre as chamadas de função é usar fechamentos. Os encerramentos foram introduzidos no PHP 5.3. Em duas palavras, eles permitem limitar o acesso a algum conjunto de variáveis dentro de um escopo de função para outra função anônima que será a única maneira de acessá-las. Estar em variáveis de fechamento pode imitar (com mais ou menos sucesso) conceitos de POO como 'constantes de classe' (se elas foram passadas em fechamento por valor) ou 'propriedades privadas' (se passadas por referência) em programação estruturada.
O último realmente permite usar closures em vez de variáveis estáticas. O que usar sempre depende do desenvolvedor decidir, mas deve-se mencionar que as variáveis estáticas são definitivamente úteis ao trabalhar com recursões e merecem ser notadas pelos desenvolvedores.
fonte
Não postarei uma resposta completa para a pergunta, pois as existentes e o manual do PHP fazem um ótimo trabalho para explicar a maior parte disso.
Mas um assunto que foi perdido foi o de superglobals , incluindo o comumente usado
$_POST
,$_GET
,$_SESSION
, etc. Essas variáveis são matrizes que estão sempre disponíveis, em qualquer âmbito, sem umaglobal
declaração.Por exemplo, esta função imprimirá o nome do usuário executando o script PHP. A variável está disponível para a função sem nenhum problema.
A regra geral de "os globais são ruins" é normalmente alterada no PHP para "os globais são ruins, mas os superglobais estão bem", desde que não se use mal. (Todas essas variáveis são graváveis, portanto, elas podem ser usadas para evitar a injeção de dependência, se você for realmente péssimo.)
Não há garantia de que essas variáveis estejam presentes; um administrador pode desativar alguns ou todos eles usando a
variables_order
directiva emphp.ini
, mas isso não é um comportamento comum.Uma lista dos superglobais atuais:
$GLOBALS
- Todas as variáveis globais no script atual$_SERVER
- Informações sobre o servidor e o ambiente de execução$_GET
- Valores passados na cadeia de consulta da URL, independentemente do método HTTP usado para a solicitação$_POST
- Valores passados em uma solicitação HTTP POST comapplication/x-www-form-urlencoded
oumultipart/form-data
tipos MIME$_FILES
- Arquivos passados em uma solicitação HTTP POST com ummultipart/form-data
tipo MIME$_COOKIE
- Cookies passados com a solicitação atual$_SESSION
- Variáveis de sessão armazenadas internamente pelo PHP$_REQUEST
- Normalmente, uma combinação de$_GET
e$_POST
, mas às vezes$_COOKIES
. O conteúdo é determinado pelarequest_order
diretiva emphp.ini
.$_ENV
- As variáveis de ambiente do script atualfonte