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:
class DecoratorPluginManager extends AbstractPluginManager
{
/**
* Default set of decorators
*
* @var array
*/
protected $invokableClasses = array(
'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
'htmltag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
'tag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
);
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:
/**
* @file
* Initiates a browser-based installation of Drupal.
*/
/**
* Root directory of Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());
/**
* Global flag to indicate that site is in installation mode.
*/
define('MAINTENANCE_MODE', 'install');
// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
exit;
}
// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();
¿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:
function xzy($var){
global $z;
$z = $var;
}
function setZ($var){
$this->z = $var;
}
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.