2010-02-18 21 views
6

A continuación se presenta el fragmento de código:Problema con el acceso a una variable global en PHP

function something() { 
$include_file = 'test.php'; 
if (file_exists($include_file)) { 
    require_once ($include_file); 
//  global $flag; 
//  echo 'in main global scope flag='.$flag; 
    test(); 
    } 
} 

something(); 

exit; 

//in test.php 

$flag = 4; 
function test() { 
    global $flag; 

    echo '<br/>in test flag="'.$flag.'"'; 
    if ($flag) { 
     echo 'flag works'; 
    //do something 
    } 
} 

El anterior fragmento de código, el valor de $ flag 'alcance global' ecos correctamente pero tampoco reconoce la bandera $ con un valor de 4, asume valor nulo por $ flag. Por favor, indique cuál es el error al acceder a esa variable global $ flag.

Gracias de antemano, Anitha

+0

Si agrego 'global $ flag;' en función algo, entonces funciona, es decir, no da el error variable indefinido. No entiendo esto. – CodeTweetie

+1

tiene que declarar el alcance de la variable dentro de una función si está tratando de usar una variable global. Su mejor práctica es no usar variables globales de todos modos. – bonez

Respuesta

2

$flag = 4; no está en el alcance global.

If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function.

- PHP página Manual para include, que también se aplica para include_once, requieren, y require_once

voy a hacer una conjetura que el error que está recibiendo está en la línea if ($flag), porque en ese punto, $ flag no está inicializado, porque a la variable global $ flag nunca se le ha asignado un valor.

Por cierto, echo 'global scope flag='.$flag; no se visualiza el indicador global tampoco, ya que se necesita un global $flag; en esa función para mostrar la copia global, que también tiene el efecto secundario de hacer $flag = 4; afecta a la copia global en el archivo incluido.

2

La línea probable que le da problemas es la siguiente: echo 'global scope flag'=$flag;

Cambiar a: echo 'global scope flag = '.$flag;

Editar: Ahora que ha editado su código snippet para envolver su código en la función something(), el problema se vuelve más claro. Creo que lo que está sucediendo aquí es que cuando inicializas $ flag con $flag = 4;, su alcance está dentro del método something().

Intente colocar $flag = 4; arriba/antes de la línea function something() {. Entonces todo estará bien con el mundo.

+0

hola, gracias por la respuesta. que era un error tipográfico, lo corrigió. Pero el problema original todavía está allí. – CodeTweetie

+0

OK, bien con esa línea corregida, no veo ningún otro problema con el código que ha publicado. Su problema está dentro del método 'test()' ¿verdad? ¿Qué sucede si accede a test.php directamente? ¿Mismo error? – Bart

0

En caso de no ser echo 'global scope flag'=$flag;echo 'global scope flag =' . $flag;

he recibido un error diferente. Lo cual me ayudó a solucionar el problema rápidamente.

Parse error: parse error, unexpected '=', expecting ',' or ';' in D:\Websites (Apache)\Test Site1\test.php on line 6

0

Sólo hacer algo como esto:

$myFlag = getFlag(); 
echo $myFlag; // output: whatever 


// test.php 

$flag = 'whatever'; 

function getFlag(){ 
    global $flag; 
    return $flag; 
} 

que no volvería a poner una variable en un script y llamarlo desde otro archivo. esto causará confusión extrema en el camino. Incluso mi solución no es la mejor. Haría esto como una clase completa con ideal.

+0

no, me hago eco de $ flag after require, lo que significa que para entonces se ha definido $ flag. ¿no? – CodeTweetie

7

Se está ejecutando un problema aquí simplemente porque la forma en que PHP interpreta actualmente su archivo. Usted tiene funciones anidadas.

Así es como su código actualmente ejecuta:

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
     //require_once ($include_file); 

     $flag = 4; 
     function test() { 
      global $flag; 

      echo '<br/>in test flag="'.$flag.'"'; 
      if ($flag) { 
       echo 'flag works'; 
      //do something 
      } 
     } 

     //end require_once ($include_file); 

     test(); 
    } 
} 

something(); 

exit; 

Como se puede ver, cuando se asigna el valor de 4-$flag ($flag = 4), que se encuentran dentro del ámbito de la función something(), no dentro del alcance global.

En test(), como declara $flag como global dentro de esa función, $flag es una variable totalmente diferente, global para todo el script.

Para evitar este problema, utilice el superglobal $GLOBALS. Es más rápido que utilizando global todos modos, y de esa manera usted no se mezclaba en asuntos de alcance como los anteriores:

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
     //require_once ($include_file); 

     $GLOBALS['flag'] = 4; 
     function test() { 
      global $flag; 

      echo '<br/>in test flag="'.$GLOBALS['flag'].'"'; 
      if ($GLOBALS['flag']) { 
       echo 'flag works'; 
      //do something 
      } 
     } 

     //end require_once ($include_file); 

     test(); 
    } 
} 

something(); 

echo $flag; //echos 4 

exit; 
+0

+1, solo para completar: 'indicador global $; require_once ($ include_file); 'también haría el truco. Pero de todos modos, toda esta cosa global/función/requiere me parece hackosa. – VolkerK

+0

En realidad, aunque esto es principalmente correcto, la función de prueba() se mueve fuera de la función something(): "todas las funciones y clases definidas en el archivo incluido tienen el alcance global". http://php.net/include – Powerlord

+0

Pero sucede lo mismo si escribe literalmente la definición de la función en la función "externa". Entonces el ejemplo es correcto en este punto también. – VolkerK

0

Desde su pregunta original ya ha sido contestada permítanme sugerir otro enfoque que evita las variables globales en conjunto .
Aparentemente tiene una función + un valor predeterminado que establece como una variable global. También puede definir default values for function parameters.

<?php // test.php 
function test($flags=4) { 
    echo '<br/>in test flag="'.$flags.'"'; 
    if ($flags!=0) { 
    echo ' flag works'; 
    } 
} 

Sin variable global, pero todavía se puede llamar a prueba de() sin un parámetro y la función utilizará el valor por defecto - que se puede sobrescribir pasando el parámetro.

function something() { 
    $include_file = 'test.php'; 
    if (file_exists($include_file)) { 
    require_once ($include_file); 
    echo "\nwithout parameter: "; test(); 
    echo "\nwith a parameter: "; test(16); 
    } 
} 
something(); 
exit; 

impresiones

without parameter: <br/>in test flag="4" flag works 
with a parameter: <br/>in test flag="16" flag works 

eso no es exactamente el mismo comportamiento, pero que puede ser lo que quería en primer lugar ....

edición: Otro punto podría ser el

if (file_exists($include_file)) { 
    require_once ($include_file); 

construcción que estás utilizando. No tengo una opinión fuerte (o ninguna evidencia fuerte ;-)) en eso, sino que puede ser que desee considerar el uso

$something = include $include_file; 
if (false!==$something) { /* error handling here... */ } 

lugar. include "devuelve" falso si php no puede incluir el archivo. Todo lo que se requiere para que esto funcione es que el archivo incluido no devuelve FALSO explícitamente. Este podría ser menos caché (por ejemplo, cuando se utiliza algo como APC). Pero de nuevo: no tengo pruebas para esto, solo una corazonada. Al menos le da a su código la posibilidad de manejar un error "con gracia".

Cuestiones relacionadas