El uso de globales hace que su código sea difícil de probar, por lo que es más propenso a errores, no es seguro e impredecible. Es por eso que pasamos las variables que queremos dentro de una función / objeto. Entonces mi pregunta es simple:
¿Violan $ _POST, $ _GET, etc., el principio de encapsulación ?
Estoy pensando que, para retener el control de esas variables de una manera OO, una solución ideal sería agregar algunas líneas como esta al 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);
No he visto esto en ningún lado, ni siquiera un tutorial ni recomendación. Además, podemos ver claramente cómo el código anterior es mucho más fácil de probar que uno que incluye $Person = new Person($DB, $_GET['id']);
o incluso (lo feo), $Person = new Person($DB);
ya que puede usar un $get
objeto simulado .
¿El código anterior está en la dirección correcta o me falta algo?
EDITAR: Después de un poco de investigación ( Zend framework y Cake PHP ) como sugirió Alexander Kuzmin, parece ser lo correcto. Probablemente sean demasiado grandes para que yo pueda cavar en el código ATM, pero lo tendré en cuenta.
fuente
Respuestas:
No estoy seguro de por qué se aplica
json_decode
a$_GET
“convertir a un una matriz”;$_GET
Ya es una matriz.El uso de los superglobales (
$_GET
,$_POST
etc.) es una violación del principio de encapsulación. Pero ha habido una línea trazada donde dejas de encapsular cosas. Solicitar datos es un buen candidato para la encapsulación, pero no se deje engañar por la trampa de intentar encapsular todas las cosas .La mayoría de los frameworks generalmente envuelven los superglobales de PHP en alguna forma de objeto de solicitud. Hacer esto hace que sea más fácil burlarse de las pruebas, etc. El enfoque más simple sería:
Es simple y rudimentario, pero hace el trabajo. También es recomendable filtrar los datos en este punto, para defenderse de las inyecciones de XSS.
Pero está envuelto en un
Request
objeto. ElRequest
objeto tiene cuatro matrices, y estas matrices se pueden burlar fácilmente:fuente
// Convert the $_GET array to an object
. Además, esta respuesta stackoverflow.com/a/1869147 es la razón por la que lo estoy haciendo. Aparte de ese pequeño detalle, muchas gracias por una respuesta tan completa con consejos adicionales, eso es muy similar a lo que pretendía hacer.$_GET
datos en un objeto. Las matrices no están sucias. Siento que las personas evitan las matrices porque sienten que "no son POO", al igual que nadie se atrevería a usar un<table>
HTML por temor a no ser semántico, incluso con datos tabulares. Toma la$_GET
matriz. ¿Qué sucede si paso datos de matriz desde mi formulario, es decir<input type="checkbox" name="foo[]" />
o<select name="bar[]" multiple="multiple">
? ¿Los vas a convertir en objetos o los dejarás como están? Simplemente deje la$_GET
matriz como una matriz, según lo previsto.GET
yPOST
datos), entonces probablemente no necesite ser un objeto.Usar superglobales
$_{POST,GET,SERVER}
o lo que sea que viole la encapsulación.Este problema crece cuando quiere crear "solicitudes locales" dentro del lado del servidor de su aplicación como lo hacen muchos frameworks hoy en día.
No estoy acostumbrado a trabajar con frameworkds, pero lo que suelo hacer es crear un par de Solicitud / Respuesta al comienzo de mi procesamiento. La solicitud contiene los valores de estos parámetros globales.
Si quiero crear una subrequest del lado del servidor, tengo dos opciones: usar el contexto actual o crear uno completamente nuevo. Entonces, creo que no deberías desarmar estas variables superglobales porque QUIZÁS querrías usarlas nuevamente. Además, por esta razón, no estoy de acuerdo con que los parámetros de solicitud sean singletons.
Al contener solo valores, no referencias a estas superglobales, un cambio en un objeto Request nunca afectará a otro, por lo que se resuelve el problema con el estado global.
Entonces, básicamente, tengo dos opciones:
fuente
POST- y GET-vars se envían al servidor de forma masiva y php tiene que tener sentido. En cierto modo, tiene sentido tenerlos disponibles en todo el mundo, para que el desarrollador pueda elegir dónde procesarlos.
Muchos frameworks (como CakePHP, por ejemplo) leen los Parámetros y luego los colocan en una matriz, objeto o estructura similar. Después de eso, se manejan como cualquier otro dato y se pasan a todos los métodos que los necesitan.
fuente
index.php
?La encapsulación es un buen principio cuando existe la posibilidad de que necesite varias instancias de algo. Pero solo hay un conjunto de parámetros para una página web. Si estuvieran en una clase en lugar de variables globales, probablemente serían singletons. No hay una mejora significativa al pasar de las variables globales a las clases singleton, es solo una sintaxis diferente para acceder a ellas. Todavía son objetos intrínsecamente globales, es más engorroso porque tienes que controlar la instancia de clase y pasarla.
Como se accede a estos parámetros con tanta frecuencia, los diseñadores de PHP tomaron la decisión de facilitar su acceso, en lugar de adherirse a principios de diseño rígidos. Es una buena idea hacer que las operaciones más comunes sean convenientes, de lo contrario los programadores lo maldecirán por hacer que vuelvan a escribir lo mismo, siempre.
fuente
If they were in a class instead of global variables, they would probably be singletons
ya que los singletons también están en el ámbito global . Solo digo que se elimine por completo ese estado global y se convierta en local, tomando prestada esta idea de The Clean Code Talks - "Global State and Singletons" . Se expresa mi principal preocupación al hacer esta pregunta: pruebas . Desafortunadamente, parece que no leyó toda la pregunta, sino solo el título$get
de una función a otra.