¿Cuál es la utilidad de la palabra clave global ?
¿Hay alguna razón para preferir un método a otro?
- ¿Seguridad?
- ¿Actuación?
- ¿Algo más?
Método 1:
function exempleConcat($str1, $str2)
{
return $str1.$str2;
}
Método 2:
function exempleConcat()
{
global $str1, $str2;
return $str1.$str2;
}
¿Cuándo tiene sentido usarlo global
?
Para mí, parece peligroso ... pero puede ser solo una falta de conocimiento. Estoy interesado en razones técnicas documentadas (por ejemplo, con ejemplo de código, enlace a documentación ...).
¡Gracias por adelantado!
Generosidad
Esta es una buena pregunta general sobre el tema, yo (@Gordon) estoy ofreciendo una recompensa para obtener respuestas adicionales. No importa si su respuesta está de acuerdo con la mía o da un punto de vista diferente. Dado que el global
tema surge de vez en cuando, podríamos usar una buena respuesta "canónica" para enlazar.
php
language-design
Pascal Qyy
fuente
fuente
goto
? ¿Por qué la gente lo usa? No lo usan (al menos espero): PRespuestas:
Los globales son malvados
Esto es cierto para la
global
palabra clave, así como para todo lo demás que va desde un alcance local hasta el alcance global (estática, singletons, registros, constantes). No quieres usarlos. Una llamada a función no debería tener que depender de nada externo, por ejemploTodo esto hará que su código dependa del exterior. Lo que significa que debe conocer el estado global completo en el que se encuentra su aplicación antes de poder llamar de manera confiable a cualquiera de estos. La función no puede existir sin ese entorno.
El uso de superglobales puede no ser un defecto obvio, pero si llama a su código desde una línea de comandos, no tiene
$_GET
o$_POST
. Si su código se basa en la entrada de estos, se está limitando a un entorno web. Simplemente abstraiga la solicitud en un objeto y utilícelo en su lugar.En caso de acoplar nombres de clases codificados de forma rígida (estáticos, constantes), su función tampoco puede existir sin que esa clase esté disponible. Eso es un problema menor cuando se trata de clases del mismo espacio de nombres, pero cuando comienzas a mezclar desde diferentes espacios de nombres, estás creando un lío enredado.
La reutilización se ve gravemente obstaculizada por todo lo anterior. También lo es la prueba unitaria .
Además, las firmas de sus funciones mienten cuando se acopla al alcance global
es un mentiroso, porque afirma que puedo llamar a esa función sin pasarle nada. Es solo cuando miro el cuerpo de la función que aprendo que tengo que configurar el entorno en un cierto estado.
Si su función requiere argumentos para ejecutarse, explíquelos y páselos:
transmite claramente de la firma lo que requiere para ser llamado. No depende del medio ambiente estar en un estado específico. No tienes que hacer
Es una cuestión de introducir (palabra clave global) frente a introducir (argumentos). Cuando empuja / inyecta dependencias, la función ya no depende del exterior. Cuando lo hace
fn(1)
, no tiene que tener una variable que contenga 1 en algún lugar exterior. Pero cuando ingresa global$one
dentro de la función, se acopla al alcance global y espera que tenga una variable de eso definida en algún lugar. Entonces, la función ya no es independiente.Peor aún, cuando está cambiando globales dentro de su función, su código rápidamente será completamente incomprensible, porque sus funciones están teniendo efectos secundarios por todas partes.
A falta de un mejor ejemplo, considere
Y luego lo haces
No hay forma de ver que
$foo
cambió de estas tres líneas. ¿Por qué llamar a la misma función con los mismos argumentos cambiaría repentinamente su salida o cambiaría un valor en el estado global? Una función debería hacer X para una entrada definida Y. Siempre.Esto se vuelve aún más severo cuando se usa OOP, porque OOP se trata de encapsulación y al llegar al alcance global, está rompiendo la encapsulación. Todos estos Singletons y Registries que ve en los frameworks son olores de código que deben eliminarse a favor de la inyección de dependencia. Desacople su código.
Más recursos:
static
considerado dañinofuente
La única razón importante en contra
global
es que significa que la función depende de otro alcance. Esto se complicará muy rápidamente.vs.
Requerir
$str1
y$str2
estar configurado en el alcance de llamada para que la función funcione significa que introduce dependencias innecesarias. Ya no puede cambiar el nombre de estas variables en este ámbito sin renombrarlas también en la función y, por lo tanto, también en todos los demás ámbitos que esté utilizando esta función. Esto pronto se convierte en un caos cuando intentas realizar un seguimiento de los nombres de las variables.global
es un mal patrón incluso para incluir elementos globales como los$db
recursos. No habrá llegado el día en el que desea cambiar el nombre$db
, pero no puede, porque toda su aplicación depende del nombre.Limitar y separar el alcance de las variables es esencial para escribir cualquier aplicación medianamente compleja.
fuente
$db
? Es la DOP, que se transmite por todas partes. ¿Por qué se cambiaría cuando puedo actualizar la información de conexión por separado?$db
variable global ? ¿Porque algún día descubrirá las pruebas unitarias y necesitará administrar más de una conexión de base de datos a la vez para eso? Muchas, muchas razones.Los globales son inevitables.
Es una discusión antigua, pero aún me gustaría agregar algunos pensamientos porque los extraño en las respuestas mencionadas anteriormente. Esas respuestas simplifican demasiado lo que es global y presentan soluciones que no son en absoluto soluciones al problema. El problema es: ¿cuál es la forma correcta de tratar una variable global y el uso de la palabra clave global? Para eso, primero tenemos que examinar y describir qué es un global.
Eche un vistazo a este código de Zend y comprenda que no sugiero que Zend esté mal escrito:
Aquí hay muchas dependencias invisibles. Esas constantes son en realidad clases. También puede ver require_once en algunas páginas de este marco. Require_once es una dependencia global, por lo que crea dependencias externas. Eso es inevitable para un marco. ¿Cómo se puede crear una clase como DecoratorPluginManager sin una gran cantidad de código externo del que depende? No puede funcionar sin muchos extras. Usando el framework Zend, ¿alguna vez ha cambiado la implementación de una interfaz? Una interfaz es, de hecho, global.
Otra aplicación utilizada a nivel mundial es Drupal. Están muy preocupados por el diseño adecuado, pero al igual que cualquier gran marco, tienen muchas dependencias externas. Eche un vistazo a los globales en esta página:
¿Alguna vez ha escrito una redirección a la página de inicio de sesión? Eso está cambiando un valor global. (Y luego no está diciendo 'WTF', que considero una buena reacción a la mala documentación de su aplicación). El problema con los globales no es que sean globales, los necesita para tener una aplicación significativa. El problema es la complejidad de la aplicación general, lo que puede convertirla en una pesadilla de manejar. Las sesiones son globales, $ _POST es global, DRUPAL_ROOT es global, includes / install.core.inc 'es un global no modificable. Hay un gran mundo fuera de cualquier función que se requiera para que esa función haga su trabajo.
La respuesta de Gordon es incorrecta, porque sobrevalora la independencia de una función y llamar mentirosa a una función simplifica demasiado la situación. Las funciones no mienten y cuando echas un vistazo a su ejemplo, la función está diseñada incorrectamente; su ejemplo es un error. (Por cierto, estoy de acuerdo con esta conclusión de que se debe desacoplar el código). La respuesta de deceze no es realmente una definición adecuada de la situación. Las funciones siempre funcionan dentro de un ámbito más amplio y su ejemplo es demasiado simplista. Todos estaremos de acuerdo con él en que esa función es completamente inútil, porque devuelve una constante. Esa función es de todos modos un mal diseño. Si quiere demostrar que la práctica es mala, por favor venga con un ejemplo relevante. Cambiar el nombre de las variables a lo largo de una aplicación no es gran cosa teniendo un buen IDE (o una herramienta). La pregunta es sobre el alcance de la variable, no la diferencia de alcance con la función. Hay un momento adecuado para que una función desempeñe su papel en el proceso (por eso se crea en primer lugar) y en ese momento adecuado puede influir en el funcionamiento de la aplicación en su conjunto, por lo que también se trabaja en variables globales. . La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas: de ahí que también trabajemos en variables globales. La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas: de ahí que también trabajemos en variables globales. La respuesta de xzyfer es una declaración sin argumentación. Los globales están tan presentes en una aplicación si tiene funciones de procedimiento o diseño OOP. Las siguientes dos formas de cambiar el valor de un global son esencialmente las mismas:
En ambos casos, el valor de $ z cambia dentro de una función específica. En ambas formas de programación, puede realizar esos cambios en muchos otros lugares del código. Se podría decir que usando global podrías llamar a $ z en cualquier lugar y cambiar allí. Sí tu puedes. ¿Pero lo harás? Y cuando se hace en lugares inapropiados, ¿no debería llamarse error?
Bob Fanger comenta sobre xzyfer.
¿Alguien debería usar algo y especialmente la palabra clave 'global'? No, pero como cualquier tipo de diseño, intenta analizar de qué depende y qué depende de él. Intente averiguar cuándo cambia y cómo cambia. El cambio de valores globales solo debería ocurrir con aquellas variables que pueden cambiar con cada solicitud / respuesta. Es decir, solo a aquellas variables que pertenecen al flujo funcional de un proceso, no a su implementación técnica. El redireccionamiento de una URL a la página de inicio de sesión pertenece al flujo funcional de un proceso, la clase de implementación utilizada para una interfaz para la implementación técnica. Puede cambiar este último durante las diferentes versiones de la aplicación, pero no debe cambiarlas con cada solicitud / respuesta.
Para comprender mejor cuándo es un problema trabajar con globales y la palabra clave global y cuándo no, presentaré la siguiente oración, que proviene de Wim de Bie cuando escribo sobre blogs: 'Personal sí, privado no'. Cuando una función está cambiando el valor de una variable global en aras de su propio funcionamiento, entonces llamaré a ese uso privado de una variable global y un error. Pero cuando el cambio de la variable global se realiza para el correcto procesamiento de la aplicación en su conjunto, como la redirección del usuario a la página de inicio de sesión, entonces es que en mi opinión posiblemente sea un buen diseño, no por definición malo y ciertamente no una anti-patrón.
En retrospectiva a las respuestas de Gordon, deceze y xzyfer: todos tienen 'sí privados' (y errores) como ejemplos. Por eso se oponen al uso de globales. Yo también lo haría. Sin embargo, no vienen con ejemplos de 'sí personal, no privado' como lo he hecho en esta respuesta varias veces.
fuente
xyz
ysetZ
. El primero cambia el estado global, el segundo es un método de clase y solo cambia el estado de la instancia a la que se llamó.global
en drupal 7.26 (que es la última versión), algunos de esos accesos están en los comentarios y varios otros parecen estar en un código que no se ha tocado durante años. Espero que no usenglobal
s en drupal 8.En pocas palabras, rara vez hay una razón para hacerlo
global
y nunca una buena en el código PHP moderno en mi humilde opinión. Especialmente si está usando PHP 5. Y más especialmente si está desarrollando código orientado a objetos.Los globales afectan negativamente la capacidad de mantenimiento, la legibilidad y la capacidad de prueba del código. Muchos usos de
global
can y deben reemplazarse con Dependency Injection o simplemente pasando el objeto global como parámetro.fuente
No dude en utilizar palabras clave globales dentro de funciones en PHP. Especialmente no tome a las personas que están predicando / gritando de manera extravagante cómo los globales son 'malvados' y todo eso.
En primer lugar, porque lo que usa depende totalmente de la situación y el problema, y NO hay una única solución / forma de hacer nada en la codificación. Dejando totalmente a un lado la falacia de los adjetivos religiosos indefinibles, subjetivos como "maldad" en la ecuación.
Caso en punto :
Wordpress y su ecosistema utilizan palabras clave globales en sus funciones. Sea el código OOP o no OOP.
Y a partir de ahora Wordpress es básicamente el 18,9% de Internet, y está ejecutando los mega sitios / aplicaciones masivos de innumerables gigantes que van desde Reuters a Sony, a NYT, a CNN.
Y lo hace bien.
El uso de palabras clave globales dentro de las funciones libera a Wordpress de la hinchazón MASIVA que sucedería dado su enorme ecosistema. Imagine que cada función pregunta / pasa cualquier variable que se necesita de otro complemento, núcleo y regresa. Agregado con interdependencias de complementos, eso terminaría en una pesadilla de variables o una pesadilla de matrices pasadas como variables. Un infierno que rastrear, un infierno que depurar, un infierno que desarrollar. Huella de memoria increíblemente masiva debido a la hinchazón del código y la hinchazón variable también. Más difícil de escribir también.
Puede que haya personas que se acerquen y critiquen Wordpress, su ecosistema, sus prácticas y lo que sucede en esos lugares.
No tiene sentido, ya que este ecosistema es casi el 20% de Internet. Aparentemente, sí funciona, hace su trabajo y más. Lo que significa que es lo mismo para la palabra clave global.
Otro buen ejemplo es el fundamentalismo de "los iframes son malos". Hace una década era una herejía utilizar iframes. Y había miles de personas predicando contra ellos en Internet. Luego viene Facebook, luego vienen las redes sociales, ahora los iframes están en todas partes, desde los cuadros de 'me gusta' hasta la autenticación, y listo, todos cállate. Hay quienes todavía no se callaron, con razón o sin ella. Pero sabes qué, la vida continúa a pesar de esas opiniones, e incluso los que predicaban contra los iframes hace una década ahora tienen que usarlos para integrar varias aplicaciones sociales a las aplicaciones de su organización sin decir una palabra.
......
El fundamentalismo del codificador es algo muy, muy malo. Un pequeño porcentaje entre nosotros puede estar agraciado con el cómodo trabajo en una sólida empresa monolítica que tiene suficiente influencia para soportar el cambio constante en la tecnología de la información y las presiones que trae con respecto a la competencia, el tiempo, el presupuesto y otras consideraciones, y por lo tanto puede practicar. fundamentalismo y adhesión estricta a los "males" o "bienes" percibidos. Posiciones cómodas que recuerdan a la vejez, incluso si los ocupantes son jóvenes.
Sin embargo, para la mayoría, el mundo de las tecnologías de la información es un mundo en constante cambio en el que necesitan ser prácticos y de mente abierta. No hay lugar para el fundamentalismo, deje de lado palabras clave indignantes como "maldad" en las trincheras de primera línea de la tecnología de la información.
Simplemente use lo que tenga más sentido para el problema A MANO, con las consideraciones adecuadas para el futuro a corto, mediano y largo plazo. No evite usar ninguna función o enfoque porque tiene una animosidad ideológica desenfrenada en su contra, entre cualquier subconjunto de codificadores.
No harán tu trabajo. Vas a. Actúe de acuerdo a sus circunstancias.
fuente
Creo que todo el mundo ha expuesto bastante sobre los aspectos negativos de los globales. Así que agregaré los aspectos positivos, así como las instrucciones para el uso adecuado de los globales:
El objetivo principal de los globales era compartir información entre funciones. cuando no había nada como una clase, el código php consistía en un montón de funciones. A veces, necesitaría compartir información entre funciones. Por lo general, se utilizó el global para hacer esto con el riesgo de que los datos se corrompan al convertirlos en globales.
Ahora, antes de que un simpleton feliz y afortunado comience un comentario sobre la inyección de dependencias, me gustaría preguntarle cómo el usuario de una función como ejemplo
get_post(1)
conocería todas las dependencias de la función. También considere que las dependencias pueden diferir de unaversión a otra y de un servidor a otro. El principal problema con la inyección de dependencias es que las dependencias deben conocerse de antemano. En una situación en la que esto no es posible o las variables globales no deseadas eran la única forma de lograr este objetivo.
Debido a la creación de la clase, ahora las funciones comunes se pueden agrupar fácilmente en una clase y compartir datos. A través de implementaciones como Mediators, incluso los objetos no relacionados pueden compartir información. Esto ya no es necesario.
Otro uso de los globales es para fines de configuración. Principalmente al comienzo de un script antes de que se hayan cargado los cargadores automáticos, se hayan realizado las conexiones a la base de datos, etc.
Durante la carga de recursos, los globales se pueden usar para configurar datos (es decir, qué base de datos usar donde se encuentran los archivos de la biblioteca, la URL del servidor, etc.). La mejor forma de hacerlo es mediante el uso de la
define()
función, ya que estos valores no cambian con frecuencia y se pueden colocar fácilmente en un archivo de configuración.El uso final de los globales es contener datos comunes (es decir, CRLF, IMAGE_DIR, IMAGE_DIR_URL), indicadores de estado legibles por humanos (es decir, ITERATOR_IS_RECURSIVE). Aquí los globales se utilizan para almacenar información que está destinada a ser utilizada en toda la aplicación, lo que permite que se modifiquen y que esos cambios aparezcan en toda la aplicación.
El patrón singleton se hizo popular en php durante php4 cuando cada instancia de un objeto ocupaba memoria. El singleton ayudó a ahorrar RAM al permitir que solo se creara una instancia de un objeto. Antes de las referencias, incluso la inyección de dependencia habría sido una mala idea.
La nueva implementación php de objetos de PHP 5.4+ se encarga de la mayoría de estos problemas, ya que puede pasar objetos de forma segura con poca o ninguna penalización. Esto ya no es necesario.
Otro uso para singletons es la instancia especial donde solo debe existir una instancia de un objeto a la vez, esa instancia puede existir antes / después de la ejecución del script y ese objeto se comparte entre diferentes scripts / servidores / lenguajes, etc.Aquí un patrón singleton resuelve el solución bastante bien.
Entonces, en conclusión, si está en la posición 1, 2 o 3, entonces usar un global sería razonable. Sin embargo, en otras situaciones se debe utilizar el método 1.
No dude en actualizar cualquier otra instancia en la que se deban utilizar globales.
fuente
No tiene sentido hacer una función concat usando la palabra clave global.
Se utiliza para acceder a variables globales como un objeto de base de datos.
Ejemplo:
Se puede utilizar como una variación del patrón Singleton.
fuente