O uso de globais torna seu código difícil de testar, portanto, mais propenso a erros, não seguro e imprevisível. É por isso que passamos as variáveis que queremos dentro de uma função / objeto. Então, minha pergunta é simples:
$ _POST, $ _GET, etc violam o princípio do encapsulamento ?
Estou pensando que, para manter o controle dessas variáveis de uma maneira OO, uma solução ideal seria adicionar algumas linhas como esta ao código:
// Convert the $_GET array to an object
$get = json_decode(json_encode($_GET), FALSE); // stackoverflow.com/a/1869147
// Stop it from being included from anywhere
unset($_GET);
// Small example of what could be done later on
$DB = new PDO(/* ... */);
$Person = new Person($DB, $get->id);
Eu não vi isso em lugar nenhum, nem mesmo um tutorial ou recomendação. Além disso, podemos ver claramente como o código acima é muito mais fácil de ser testado do que aquele que inclui $Person = new Person($DB, $_GET['id']);
ou mesmo (o feio), $Person = new Person($DB);
pois você pode usar um $get
objeto simulado .
O código acima está na direção certa ou estou faltando alguma coisa?
EDIT: Depois de alguma investigação ( framework Zend e Cake PHP ), como Alexander Kuzmin sugeriu, parece ser a coisa certa a seguir. Eles provavelmente são grandes demais para eu digitar o código do caixa eletrônico, mas vou lembrar disso.
fonte
Respostas:
Eu não estou muito certo porque você aplica
json_decode
para$_GET
a “convertê-lo em um uma matriz”;$_GET
já é uma matriz.O uso das super globais (
$_GET
,$_POST
etc) é uma violação do princípio do encapsulamento. Mas deve haver uma linha traçada onde você para de encapsular as coisas. Os dados de solicitação são um bom candidato ao encapsulamento, mas não seja sugado pelo buraco do coelho ao tentar encapsular todas as coisas .A maioria das estruturas geralmente envolve as super globais do PHP em alguma forma de objeto de solicitação. Fazer isso facilita a simulação de testes, etc. A abordagem mais simples seria:
É simples e rudimentar, mas faz o trabalho. Também é aconselhável filtrar os dados neste momento, para se defender contra injeções de XSS.
Mas está envolto em um
Request
objeto. ORequest
objeto possui quatro matrizes e essas matrizes podem ser facilmente zombadas:fonte
// Convert the $_GET array to an object
. Além disso, esta resposta stackoverflow.com/a/1869147 é o motivo pelo qual estou fazendo isso. Com esses pequenos detalhes, muito obrigado por uma resposta tão completa com dicas extras, que é muito semelhante ao que eu pretendia fazer.$_GET
dados em um objeto. Matrizes não estão sujas. Sinto que as pessoas evitam as matrizes porque sentem que "não são OOP", assim como ninguém ousaria usar um<table>
em HTML por medo de ser semântico, mesmo com dados tabulares. Pegue a$_GET
matriz. O que acontece se eu passar dados de matriz do meu formulário,<input type="checkbox" name="foo[]" />
ou seja, ou<select name="bar[]" multiple="multiple">
? Você vai convertê-los em objetos ou deixá-los como estão? Apenas deixe a$_GET
matriz como uma matriz, como pretendido.GET
ePOST
dados), então provavelmente não precisa ser um objeto.O uso de superglobais
$_{POST,GET,SERVER}
ou qualquer outra coisa certamente viola o encapsulamento.Esse problema aumenta quando você deseja criar "solicitações locais" no lado do servidor do aplicativo, como muitas estruturas fazem hoje em dia.
Não estou acostumado a trabalhar com frameworkds, mas o que geralmente faço é criar um par de Solicitação / Resposta no início do meu processamento. A solicitação contém os valores desses parâmetros globais.
Se eu quiser criar uma subconsulta do lado do servidor, tenho duas opções: usar o contexto atual ou criar um totalmente novo. Então, acho que você não deve desmarcar essas variáveis superglobais porque TALVEZ desejaria usá-las novamente. Além disso, por esse motivo, discordo que os parâmetros de solicitação devem ser singletons.
Ao conter apenas valores, e não referências a esses superglobais, uma alteração em um objeto Request nunca afetará outro, portanto, o problema com o estado global é resolvido.
Então, basicamente, eu tenho duas opções:
fonte
Os vars POST e GET são enviados para o servidor em um único lote e o php precisa dar sentido a eles. De certa forma, faz sentido tê-los disponíveis globalmente, para que o desenvolvedor possa escolher onde processá-los.
Muitas estruturas (como o CakePHP, por exemplo) leem os Parâmetros e depois as colocam em alguma matriz, objeto ou estrutura semelhante. Depois disso, eles são tratados como quaisquer outros dados e são passados para todos os métodos que precisam deles.
fonte
index.php
?Encapsulamento é um bom princípio quando há uma chance de que você precise de várias instâncias de algo. Mas há apenas um conjunto de parâmetros para uma página da web. Se eles estivessem em uma classe em vez de variáveis globais, provavelmente seriam singletons. Não há melhoria significativa passando de variáveis globais para classes singleton, é apenas uma sintaxe diferente para acessá-las. Eles ainda são objetos inerentemente globais, é apenas mais complicado porque você precisa entender a instância da classe e distribuí-la.
Como esses parâmetros são acessados com tanta frequência, os designers do PHP decidiram torná-los fáceis de acessar, em vez de aderir a rígidos princípios de design. É uma boa idéia tornar as operações mais comuns convenientes, caso contrário os programadores o xingarão por fazê-los redigitar a mesma coisa, sempre.
fonte
If they were in a class instead of global variables, they would probably be singletons
pois os singletons também estão no escopo global . Estou apenas dizendo sobre excluir completamente esse estado global e torná-lo local, tomando emprestada essa idéia do The Clean Code Talks - "Estado Global e Singletons" . Expressou minha principal preocupação ao fazer esta pergunta: teste . Infelizmente, parece que você não leu toda a pergunta, mas apenas o título #$get
de uma função para outra.