Qual é a utilidade da palavra-chave global ?
Existem razões para preferir um método a outro?
- Segurança?
- Atuação?
- Algo mais?
Método 1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
Método 2:
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
Quando faz sentido usar global
?
Para mim, parece ser perigoso ... mas pode ser apenas uma falta de conhecimento. Estou interessado em razões técnicas documentadas (por exemplo, com exemplo de código, link para documentação ...).
Desde já, obrigado!
Recompensa
Esta é uma boa pergunta geral sobre o assunto, eu (@Gordon) estou oferecendo uma recompensa para obter respostas adicionais. Não importa se sua resposta está de acordo com a minha ou fornece um ponto de vista diferente. Como o global
tópico surge de vez em quando, poderíamos usar uma boa resposta "canônica" para criar um link.
php
language-design
Pascal Qyy
fonte
fonte
goto
? Por que as pessoas usam isso? Eles não usam (espero pelo menos): PRespostas:
Globais são maus
Isso é verdadeiro para a
global
palavra - chave e também para tudo o mais que vai do escopo local ao global (estática, singletons, registros, constantes). Você não quer usá-los. Uma chamada de função não deve depender de nada externo, por exemploTudo isso fará com que seu código dependa de fora. O que significa que você precisa saber o estado global completo do seu aplicativo antes de chamar qualquer um deles de forma confiável. A função não pode existir sem esse ambiente.
Usar as superglobais pode não ser uma falha óbvia, mas se você chamar seu código de uma linha de comando, não terá
$_GET
ou$_POST
. Se o seu código depende da entrada deles, você está se limitando a um ambiente da web. Basta abstrair a solicitação em um objeto e usá-lo em seu lugar.No caso de combinação de nomes de classe codificados (estáticos, constantes), sua função também não pode existir sem que essa classe esteja disponível. Isso é menos problemático quando se trata de classes do mesmo namespace, mas quando você começa a mesclar a partir de diferentes namespaces, está criando uma confusão emaranhada.
A reutilização é severamente prejudicada por todos os itens acima. O teste de unidade também .
Além disso, suas assinaturas de função estão mentindo quando você acopla ao escopo global
é um mentiroso, porque afirma que posso chamar essa função sem passar nada para ela. É apenas quando olho para o corpo funcional que aprendo que tenho que definir o ambiente em um determinado estado.
Se a sua função requer argumentos para ser executada, torne-os explícitos e passe-os em:
transmite claramente a partir da assinatura o que ela precisa para ser chamada. Não depende do ambiente estar em um estado específico. Você não tem que fazer
É uma questão de puxar (palavra-chave global) em vez de inserir (argumentos). Quando você empurra / injeta dependências, a função não depende mais do exterior. Quando você faz isso,
fn(1)
você não precisa ter uma variável segurando 1 em algum lugar externo. Mas quando você puxa global$one
dentro da função, você acopla o escopo global e espera que ele tenha uma variável definida em algum lugar. A função não é mais independente então.Pior ainda, quando você muda os globais dentro de sua função, seu código rapidamente se torna completamente incompreensível, porque suas funções estão tendo efeitos colaterais em todo o lugar.
Na falta de um exemplo melhor, considere
E então você faz
Não há como ver que
$foo
mudou nessas três linhas. Por que chamar a mesma função com os mesmos argumentos mudaria repentinamente sua saída ou mudaria um valor no estado global? Uma função deve fazer X para uma entrada Y definida. Sempre.Isso se torna ainda mais grave ao usar OOP, porque OOP é sobre encapsulamento e, ao alcançar o escopo global, você está interrompendo o encapsulamento. Todos esses singletons e registros que você vê nas estruturas são odores de código que devem ser removidos em favor da injeção de dependência. Separe seu código.
Mais recursos:
static
considerado prejudicialfonte
O único grande motivo contra
global
é que isso significa que a função depende de outro escopo. Isso vai ficar confuso muito rapidamente.vs.
Exigir
$str1
e$str2
ser configurado no escopo de chamada para que a função funcione significa que você introduz dependências desnecessárias. Você não pode mais renomear essas variáveis neste escopo sem renomeá-las na função também e, portanto, também em todos os outros escopos que você está usando esta função. Isso logo se transforma em caos, pois você está tentando controlar os nomes das variáveis.global
é um padrão ruim até mesmo para incluir coisas globais, como$db
recursos. Não vai chegar o dia em que pretende mudar o nome$db
, mas não pode, porque a sua aplicação inteira depende do nome.Limitar e separar o escopo das variáveis é essencial para escrever qualquer aplicativo meio complexo.
fonte
$db
? É o PDO, espalhado por toda parte. Por que seria alterado quando posso atualizar as informações de conexão separadamente?$db
variável global ? Porque um dia você descobrirá o teste de unidade e precisará gerenciar mais de uma conexão de banco de dados por vez para isso? Muitas, muitas razões.Globais são inevitáveis.
É uma discussão antiga, mas ainda gostaria de acrescentar algumas reflexões porque sinto falta delas nas respostas mencionadas acima. Essas respostas simplificam demais o que é um global e apresentam soluções que não são soluções para o problema. O problema é: qual a maneira adequada de lidar com uma variável global e o uso da palavra-chave global? Para isso, primeiro temos que examinar e descrever o que é um global.
Dê uma olhada neste código do Zend - e por favor, entenda que eu não sugiro que o Zend seja mal escrito:
Existem muitas dependências invisíveis aqui. Essas constantes são, na verdade, classes. Você também pode ver require_once em algumas páginas desta estrutura. Require_once é uma dependência global, portanto, criando dependências externas. Isso é inevitável para uma estrutura. Como você pode criar uma classe como DecoratorPluginManager sem muito código externo do qual depende? Não pode funcionar sem muitos extras. Usando o framework Zend, você já mudou a implementação de uma interface? Uma interface é, na verdade, global.
Outro aplicativo usado globalmente é o Drupal. Eles estão muito preocupados com o design adequado, mas, assim como qualquer grande framework, eles têm muitas dependências externas. Dê uma olhada nos globais nesta página:
Já escreveu um redirecionamento para a página de login? Isso está mudando um valor global. (E então você não está dizendo 'WTF', que considero uma boa reação à má documentação do seu aplicativo.) O problema com os globais não é que sejam globais, você precisa deles para ter um aplicativo significativo. O problema é a complexidade do aplicativo geral, que pode torná-lo um pesadelo de lidar. As sessões são globais, $ _POST é global, DRUPAL_ROOT é global, o includes / install.core.inc 'é um global não modificável. Existe um grande mundo fora de qualquer função necessária para permitir que essa função faça seu trabalho.
A resposta de Gordon está incorreta, porque ele superestima a independência de uma função e chamar uma função de mentirosa é simplificar demais a situação. Funções não mentem e quando você dá uma olhada em seu exemplo, a função é projetada incorretamente - seu exemplo é um bug. (A propósito, concordo com a conclusão de que devemos desacoplar o código.) A resposta do deceze não é realmente uma definição adequada da situação. As funções sempre funcionam dentro de um escopo mais amplo e seu exemplo é muito simplista. Todos concordaremos com ele que essa função é totalmente inútil, porque retorna uma constante. Essa função é, de qualquer forma, um design ruim. Se você quiser mostrar que a prática é ruim, venha com um exemplo relevante. Renomear variáveis em um aplicativo não é grande coisa ter um bom IDE (ou uma ferramenta). A questão é sobre o escopo da variável, não a diferença de escopo com a função. Existe um momento adequado para uma função desempenhar seu papel no processo (é por isso que ela é criada em primeiro lugar) e nesse momento adequado pode influenciar o funcionamento da aplicação como um todo, portanto, também trabalhando em variáveis globais . A resposta de xzyfer é uma declaração sem argumentação. Os globais estão presentes em um aplicativo se você tiver funções procedurais ou design OOP. As próximas duas maneiras de alterar o valor de um global são essencialmente as mesmas: portanto, também trabalhando em variáveis globais. A resposta de xzyfer é uma declaração sem argumentação. Os globais estão presentes em um aplicativo se você tiver funções procedurais ou design OOP. As próximas duas maneiras de alterar o valor de um global são essencialmente as mesmas: portanto, também trabalhando em variáveis globais. A resposta de xzyfer é uma declaração sem argumentação. Os globais estão presentes em um aplicativo se você tiver funções procedurais ou design OOP. As próximas duas maneiras de alterar o valor de um global são essencialmente as mesmas:
Em ambos os casos, o valor de $ z é alterado em uma função específica. Em ambas as formas de programação, você pode fazer essas alterações em vários outros locais do código. Você poderia dizer que usando global você poderia chamar $ z em qualquer lugar e mudar lá. Sim você pode. Mas você vai? E quando feito em locais inadequados, não deveria ser chamado de bug?
Bob Fanger comenta sobre xzyfer.
Alguém deveria usar qualquer coisa, especialmente a palavra-chave 'global'? Não, mas como qualquer tipo de projeto, tente analisar o que depende e o que depende disso. Tente descobrir quando ele muda e como ele muda. A alteração dos valores globais só deve acontecer com as variáveis que podem ser alteradas a cada solicitação / resposta. Ou seja, apenas para aquelas variáveis que pertencem ao fluxo funcional de um processo, não à sua implementação técnica. O redirecionamento de uma URL para a página de login pertence ao fluxo funcional de um processo, a classe de implementação usada para uma interface para a implementação técnica. Você pode alterar o último durante as diferentes versões do aplicativo, mas não deve alterá-los a cada solicitação / resposta.
Para entender melhor quando é um problema trabalhar com globais e a palavra-chave global e quando não, vou apresentar a próxima frase, que vem de Wim de Bie ao escrever sobre blogs: 'Pessoal sim, privado não'. Quando uma função está mudando o valor de uma variável global para seu próprio funcionamento, chamarei esse uso privado de uma variável global e um bug. Mas quando a alteração da variável global é feita para o processamento adequado da aplicação como um todo, como o redirecionamento do usuário para a página de login, então isso na minha opinião é possivelmente um bom design, não por definição ruim e certamente não um anti-padrão.
Em retrospecto, as respostas de Gordon, deceze e xzyfer: todos eles têm 'sim privado' (e bugs) como exemplos. É por isso que eles se opõem ao uso de globais. Eu faria também Eles, no entanto, não vêm com exemplos de 'sim pessoal, não particular' como fiz nesta resposta várias vezes.
fonte
xyz
esetZ
. O primeiro altera o estado global, o segundo é um método de classe e apenas altera o estado da instância em que foi chamado.global
no drupal 7.26 (que é a versão mais recente), algumas dessas ocorrências estão em comentários e várias outras parecem estar em um código que não é alterado há anos. Espero que eles não usemglobal
s no drupal 8.Simplificando, raramente há uma razão
global
e nunca uma boa no código PHP moderno IMHO. Especialmente se você estiver usando PHP 5. E ainda mais se você desenvolver código Orientado a Objetos.Globais afetam negativamente a manutenibilidade, legibilidade e testabilidade do código. Muitos usos de
global
podem e devem ser substituídos por injeção de dependência ou simplesmente passando o objeto global como um parâmetro.fonte
Não hesite em usar palavras-chave globais dentro de funções em PHP. Especialmente não aceite pessoas que estão bizarramente pregando / gritando como os globais são "maus" e outros enfeites.
Em primeiro lugar, porque o que você usa depende totalmente da situação e do problema, e NÃO existe uma solução / maneira de fazer nada na codificação. Deixando totalmente de lado a falácia de adjetivos religiosos subjetivos e indefiníveis como "mal" na equação.
Caso em questão :
Wordpress e seu ecossistema usam palavras-chave globais em suas funções. Seja o código OOP ou não OOP.
E a partir de agora o Wordpress é basicamente 18,9% da internet, e está rodando os enormes megasites / apps de inúmeros gigantes, desde Reuters a Sony, NYT e CNN.
E funciona bem.
O uso de palavras-chave globais dentro de funções libera o Wordpress do inchaço MASSIVO que aconteceria devido ao seu enorme ecossistema. Imagine que cada função solicite / passe qualquer variável necessária de outro plugin, núcleo e retorne. Adicionado com interdependências de plug-ins, que terminariam em um pesadelo de variáveis ou um pesadelo de matrizes passadas como variáveis. Um inferno para rastrear, um inferno para depurar, um inferno para desenvolver. Pegada de memória absurdamente massiva devido ao inchaço de código e de variável também. Mais difícil de escrever também.
Pode haver gente que venha criticar o Wordpress, seu ecossistema, suas práticas e o que se passa por ali.
Inútil, já que esse ecossistema é praticamente 20% de quase toda a Internet. Aparentemente, FUNCIONA, faz seu trabalho e muito mais. O que significa o mesmo para a palavra-chave global.
Outro bom exemplo é o fundamentalismo "iframes são maus". Uma década atrás, era uma heresia usar iframes. E havia milhares de pessoas pregando contra eles na internet. Em seguida, vem o Facebook, depois vem o social, agora os iframes estão em toda parte, de caixas de 'curtir' a autenticação e voila - calem a boca. Existem aqueles que ainda não se calaram - com ou sem razão. Mas você sabe o quê, a vida continua, apesar dessas opiniões, e até mesmo aqueles que pregavam contra os iframes há uma década agora estão tendo que usá-los para integrar vários aplicativos sociais aos aplicativos de suas próprias organizações sem dizer uma palavra.
......
Fundamentalismo Coder é algo muito, muito ruim. Uma pequena porcentagem entre nós pode ser agraciada com o trabalho confortável em uma empresa sólida e monolítica que tem influência suficiente para suportar as constantes mudanças na tecnologia da informação e as pressões que ela traz em relação à competição, tempo, orçamento e outras considerações e, portanto, pode praticar fundamentalismo e adesão estrita aos "males" ou "bens" percebidos. Posições confortáveis que lembram a velhice, mesmo se os ocupantes forem jovens.
Para a maioria, entretanto, o mundo das TI é um mundo em constante mudança, no qual eles precisam ter a mente aberta e ser práticos. Não há lugar para o fundamentalismo, deixe de lado palavras-chave ultrajantes como "mal" nas trincheiras da linha de frente da tecnologia da informação.
Basta usar o que for mais adequado para o problema À MÃO, com as devidas considerações para um futuro próximo, médio e longo. Não hesite em usar qualquer recurso ou abordagem porque existe uma animosidade ideológica galopante contra ele, entre qualquer subconjunto de codificadores.
Eles não farão o seu trabalho. Você irá. Aja de acordo com suas circunstâncias.
fonte
Acho que todo mundo expôs bastante sobre os aspectos negativos dos globais. Portanto, adicionarei os aspectos positivos, bem como as instruções para o uso adequado de globais:
O principal objetivo dos globais era compartilhar informações entre funções. de volta quando não havia nada como uma classe, o código php consistia em um monte de funções. Às vezes, você precisa compartilhar informações entre as funções. Normalmente, o global foi usado para fazer isso com o risco de ter os dados corrompidos ao torná-los globais.
Agora, antes de algum simplório feliz e feliz começar um comentário sobre injeção de dependência, eu gostaria de perguntar a você como o usuário de uma função como exemplo
get_post(1)
saberia todas as dependências da função. Considere também que as dependências podem diferir deversão para versão e de servidor para servidor. O principal problema com a injeção de dependência é que as dependências precisam ser conhecidas de antemão. Em uma situação em que isso não seja possível ou variáveis globais indesejadas fossem a única maneira de atingir esse objetivo.
Devido à criação da classe, agora as funções comuns podem ser facilmente agrupadas em uma classe e compartilhar dados. Por meio de implementações como Mediadores, até objetos não relacionados podem compartilhar informações. Isso não é mais necessário.
Outro uso para globais é para fins de configuração. Principalmente no início de um script, antes que os carregadores automáticos sejam carregados, as conexões de banco de dados sejam feitas, etc.
Durante o carregamento de recursos, os globais podem ser usados para configurar dados (ou seja, qual banco de dados usar, onde os arquivos da biblioteca estão localizados, a url do servidor, etc.). A melhor maneira de fazer isso é usando a
define()
função, pois esses valores não mudam com freqüência e podem ser facilmente colocados em um arquivo de configuração.O uso final para globais é manter dados comuns (ou seja, CRLF, IMAGE_DIR, IMAGE_DIR_URL), sinalizadores de status legíveis por humanos (ou seja, ITERATOR_IS_RECURSIVE). Aqui, os globais são usados para armazenar informações que devem ser usadas em todo o aplicativo, permitindo que sejam alteradas e tenham essas alterações exibidas em todo o aplicativo.
O padrão singleton se tornou popular no php durante o php4, quando cada instância de um objeto ocupava memória. O singleton ajudou a salvar ram, permitindo apenas a criação de uma instância de um objeto. Antes das referências, mesmo a injeção de dependência teria sido uma má ideia.
A nova implementação de php de objetos do PHP 5.4+ cuida da maioria desses problemas, você pode passar objetos com segurança com pouca ou nenhuma penalidade mais. Isso não é mais necessário.
Outro uso para singletons é a instância especial em que apenas uma instância de um objeto deve existir por vez, essa instância pode existir antes / depois da execução do script e esse objeto é compartilhado entre diferentes scripts / servidores / linguagens etc. Aqui, um padrão singleton resolve o solução muito bem.
Concluindo, se você está na posição 1, 2 ou 3, usar um global seria razoável. No entanto, em outras situações, o Método 1 deve ser usado.
Sinta-se à vontade para atualizar quaisquer outras instâncias em que globais devam ser usados.
fonte
Não faz sentido criar uma função concat usando a palavra-chave global.
É usado para acessar variáveis globais, como um objeto de banco de dados.
Exemplo:
Ele pode ser usado como uma variação do padrão Singleton
fonte