PHP Mejores prácticas de variables globales


Ejemplo

Podemos ilustrar este problema con el siguiente pseudo-código

function foo() {
    global $bob;
    $bob->doSomething();
}

Tu primera pregunta aquí es obvia.

¿De dónde vino $bob ?

¿Estas confundido? Bueno. Acaba de aprender por qué los globales son confusos y se consideran una mala práctica .

Si se tratara de un programa real, su siguiente diversión es ir rastreando todas las instancias de $bob y espero que encuentre la correcta (esto empeora si $bob se usa en todas partes). Peor aún, si alguien más va y define $bob (o si olvidó y reutilizó esa variable), su código puede romperse (en el ejemplo de código anterior, tener el objeto equivocado o no tener ningún objeto, causaría un error fatal).

Dado que prácticamente todos los programas PHP hacen uso de código como include('file.php'); su trabajo para mantener un código como este se vuelve exponencialmente más difícil cuanto más archivos agregue.

Además, esto hace que la tarea de probar sus aplicaciones sea muy difícil. Supongamos que utiliza una variable global para mantener su conexión de base de datos:

$dbConnector = new DBConnector(...);

function doSomething() {
    global $dbConnector;
    $dbConnector->execute("...");
}

Para realizar una prueba unitaria de esta función, debe anular la variable global $dbConnector , ejecutar las pruebas y luego restablecerla a su valor original, que es muy propenso a errores:

/**
 * @test
 */
function testSomething() {
     global $dbConnector;

     $bkp = $dbConnector; // Make backup
     $dbConnector = Mock::create('DBConnector'); // Override

     assertTrue(foo());

     $dbConnector = $bkp; // Restore
}

¿Cómo evitamos los Globales?

La mejor manera de evitar los globales es una filosofía llamada inyección de dependencia . Aquí es donde pasamos las herramientas que necesitamos a la función o clase.

function foo(\Bar $bob) {
    $bob->doSomething();
}

Esto es mucho más fácil de entender y mantener. No se puede adivinar dónde se configuró $bob porque la persona que llama es responsable de saberlo (nos pasa lo que necesitamos saber). Mejor aún, podemos usar declaraciones de tipo para restringir lo que se está pasando.

Así que sabemos que $bob es una instancia de la clase Bar o una instancia de un hijo de Bar , lo que significa que sabemos que podemos usar los métodos de esa clase. Combinado con un autocargador estándar (disponible desde PHP 5.3), ahora podemos rastrear dónde se define Bar . PHP 7.0 o posterior incluye declaraciones de tipo expandido, donde también puede usar tipos escalares (como int o string ).

4.1

Variables superglobales

Los superglobales en PHP son variables predefinidas, que están siempre disponibles, a las que se puede acceder desde cualquier ámbito a lo largo del script.

No hay necesidad de hacer $ variable global; Para acceder a ellos dentro de funciones / métodos, clases o archivos.

Estas variables superglobal de PHP se enumeran a continuación: