2

Creo que se ha discutido bastante sobre el asunto de las variables globales.

Por ejemplo hay estas preguntas y otras más sobre el tema:

Pero a mí todavía no me queda claro del todo el ámbito de una variable global... y el ciclo de vida mucho menos.

Dado un script cualquiera, tengo varias funciones dentro de él.

Esto es lo que he entendido (aunque no acepto que sea así). Si dentro de las funciones yo quiero usar un objeto de conexión a la base de datos.

(A) Lo que entiendo

$objPDO=new DbPDO();

function unaFuncion(){

    /*
     *Aquí $objPDO es nulo, este no es su ámbito.
    */ 

}

function otraFuncion($objPDO){
    /*
     *Aquí $objPDO es recibido en parámetro y funciona.
     *Eso se entiende
    */ 
}

(B) Lo que no entiendo

Si yo quiero evitar tener que pasar mi objeto en parámetro, e intento esto:

global $objPDO;
$objPDO=new DbPDO();

function unaFuncion(){

    /*
     *Aquí, pensando que $objPDO es global
     *intento usarlo, pero me dice que es nulo
    */ 

}

function otraFuncion($objPDO){

    /*
     *Aquí $objPDO es recibido en parámetro.
     *y funciona siendo global o no
    */ 

}

Pregunta

  • ¿Por qué en la parte (B), si he declarado la variable como global no la reconoce como tal si intento usarla en unaFuncion()?

    El error que me da es:

Uncaught Error: Call to a member function on null

  • ¿Si la variable se queda declarada como global, seguirá existiendo cuando el script donde la declaré haya terminado?
A. Cedano
  • 86,578
  • 19
  • 122
  • 221
  • En tu ejemplo estas diciendo que se use una variable global en el espacio global, algo redundante. En la función que tiene su propio espacio local no indicas que quieres usar esa variable global. El uso que esperas solo es válido para las superglobales, funciones y clases. Que pueden ser usadas desde cualquier punto del programa. El ciclo de vida sería desde que se declara hasta que se destruye (depende el ámbito o el uso de unset para eliminarla por ejemplo) o finaliza el Script. – Xerif Nov 17 '17 at 14:35
  • Siento no dar una respuesta más extensa y detallada ahora mismo, pero si nadie se presta intentare hacerlo cuando disponga de más tiempo. Un saludo. – Xerif Nov 17 '17 at 14:36
  • @Xerif se agradecería una respuesta que arroje luz sobre el tema, aunque no sea ahora mismo. – A. Cedano Nov 17 '17 at 21:09

2 Answers2

3

En PHP podemos distinguir fácilmente 3 modalidades de variables según su ámbito (existen más).

  1. Variables superglobales (son variables predefinidas).
  2. Variables de ámbito simple (definidas en el ámbito general).
  3. Variables de ámbito local (definidas en funciones).

Variables superglobales

  • Son creadas automáticamente por PHP al ejecutar el script.
  • Las variables superglobales pueden ser accedidas desde cualquier punto del script, incluyendo funciones, clases ...
  • Todas ellas son matrices (arrays).
  • Su ciclo de vida es el del script , aún que algunas como $_SESSION almacenen su valor fuera del script al finalizar este para lograr la persistencia de los datos.
  • Lista: $GLOBALS, $_SERVER, $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION, $_REQUEST, $_ENV `

Variables de ámbito simple

  • Son definidas por el programador.
  • Pueden ser accedidas en cualquier parte del ámbito generar del script.
  • Pueden ser importadas/accedidas al/desde ámbito local de una función mediante global y/o $GLOBALS. Estos dos métodos son muy similares a primera vista, su diferencia radica en el comportamiento al utilizar referencias.
  • Su ciclo de vida va desde que se declara hasta que finaliza el script o se destruye la variable (unset).

Variables de ámbito local

  • Son definidas por el programador.
  • Pueden ser accedidas solo desde el ámbito local, es decir solo desde dentro de la misma función.
  • Pueden ser "exportadas" al ámbito global mediante el uso de global y/o $GLOBALS. Realmente no es una exportación, lo que sucede es que se puede crear variables desde el ámbito local en el ámbito simple o general.
  • Su ciclo de vida va desde que es declarada en el ámbito local hasta que se retorna al ámbito simple o general. Hay exceciones en esto por ejemplo si declaramos una variable como static o global.

Bien veamos que esta sucediendo en el ejemplo B por partes:

global $objPDO;
$objPDO = new DbPDO();

A) En esta parte estamos declarando o impotando la variable $objPDO al ámbito simple o general del script, esto no tendra ningún efecto a no ser que el archivo sea incluido dentro de una función.


function unaFuncion(){
    /**
     * Aquí, pensando que $objPDO es global
     * intento usarlo, pero me dice que es nulo
     */ 
}

B) En esta parte la variable $objPDO no existe dentro de la función ya que no fué impotada o declarada en el mismo.


function otraFuncion($objPDO){
    /**
     * Aquí $objPDO es recibido en parámetro.
     * y funciona siendo global o no
     */ 
}

C) Esta parte requiere de poca aclaración, $objPDO esta presente en la función ya que se paso como parámetro.


Se ha de tener en cuenta que en PHP a diferencia de lo que puede ocurrir en otros lenguajes las variables por defecto solo pueden ser accedidas desde el propio ámbito al que pertenecen (exceptuando las superglobales), esto es así por temas de legibilidad del código.

Por eso desde mi punto de vista es mas acertado dividir los ambitos de PHP en 3: superglobal, simple/global y local.

Más informacion en:

Xerif
  • 7,283
  • 3
  • 17
  • 41
  • @A. Cedano espero no haber creado mas confusión con mi respuesta. cualquier duda intertare aclararla. un saludo. – Xerif Nov 19 '17 at 15:29
0

Yendo a la documentación, podemos ver que hay que hacer algún tipo de import. o usar la variable reservada de $GLOBALS[];

<?php 

global $objPDO;
$objPDO= 5;

function unaFuncion(){

    global $objPDO;
    echo $objPDO. "\n";
    echo $GLOBALS['objPDO'];
}

function otraFuncion($objPDO){

    /*
     *Aquí $objPDO es recibido en parámetro.
     *y funciona siendo global o no
    */ 

}

echo unaFuncion();

He cambiado un poco la función para hacer las pruebas. Esto si mal no entiendo la documentación es porque de lo contrario php tomará la variable como local.

http://php.net/manual/es/language.variables.scope.php#language.variables.scope.global

Sr1871
  • 4,737
  • 1
  • 8
  • 16