dongxin2734 2014-12-31 19:18
浏览 38

这个奇怪的PHP全局变量范围是什么?

There is A LOT concerning proper global variables use, and I'm about to request further clarification. Many of the posts dating back 3 years asked, "How do I make variables included in a function, global in scope."

My assumption is that their code looks like this, since no explicit examples were given:

Example 1

#global_vars.php
<?
$my_global_var = "Hello World";
?>

#index.php
<?
function foo ()
{
   include_once ("global_vars.php");
   global $my_global_var;
   print ("my global var = [" . $my_global_var . "]<BR>");
   print ("complete<BR>");
}

foo ();
?>

which outputs:

my global var = [] 
complete

Example 2

Now, if "globals_var.php" is changed to:

<?
global $my_global_var;
$my_global_var = "Hello World";
?>

The results are:

my global var = [Hello World]
complete

Example 3

Now before you write and state that this type of global variable use is not advised, there are practical uses of global variables. And that most global variable are encapsulated in objects as a constant or as a function:

#global_vars.php
<?
class Globals 
{
    const my_global_var = "Hello World";

    public static $my_global_var2 = "Hello World";

    static function my_global_var3 ($newValue = null)
    {
        if (isset ($newValue))
            self::$my_global_var2 = $newValue;

        return (self::$my_global_var2);
    }
}
?>

#index.php
<?
function foo ()
{
    include_once ("global_vars.php");
    print ("my global var = [" . Globals::my_global_var . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3() . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3("Hi There") . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3() . "]<BR>");
    print ("complete<BR>");
}

foo ();
?>

The output is:

my global var = [Hello World]
my global var = [Hello World]
my global var = [Hi There]
my global var = [Hi There]
complete

Example 4

Of course at this point the "include_once" statement could be moved outside the function to get the same results.

#index.php
<?
include_once ("global_vars.php");

function foo ()
{
    print ("my global var = [" . Globals::my_global_var . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3() . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3("Hi There") . "]<BR>");
    print ("my global var = [" . Globals::my_global_var3() . "]<BR>");
    print ("complete<BR>");
}

foo ();
?>

The output:

my global var = [Hello World]
my global var = [Hello World]
my global var = [Hi There]
my global var = [Hi There]
complete

Example 5

In this example, the file is included outside the function. Everything works as explained by the PHP.net documentation.

#global_vars.php
<?
$my_global_var = "Hello World";
?>

#index.php
<?
include_once ("global_vars.php");

function foo ()
{
    global $my_global_var;

    print ("my global var = [" . $my_global_var . "]<BR>");
    $my_global_var = "Hi There";
    print ("my global var = [" . $my_global_var . "]<BR>");
}

foo ();
?>

Question ...

Now for my question ... If there is no namespace, why are variables included in Example 1 not to placed in $GLOBALS? And, why are these variables not considered part of the function scope? What's going on here?

Example 1 - GLOBALS / Defined Vars

#index.php
<?

function foo ()
{
    include_once ("global_vars.php");

    global $my_global_var;

    print ("my global var = [" . $my_global_var . "]<BR>");

    print ("<pre>");
    print_r ($GLOBALS);
    print ("</pre>");

    print ("<pre>");
    print_r (get_defined_vars ());
    print ("</pre>");

}

foo ();
?>

The output is:

my global var = []

Array
(
    [_GET] => Array ()
    [_POST] => Array ()
    [_COOKIE] => Array  ( ... )
    [_FILES] => Array ()
    [GLOBALS] => Array
 *RECURSION*
    [my_global_var] => 
)

Array
(
    [my_global_var] => 
)

Example 2 - GLOBALS / Defined Vars

my global var = [Hello World]

Array
(
    [_GET] => Array ()
    [_POST] => Array ()
    [_COOKIE] => Array  ( ... )
    [_FILES] => Array ()
    [GLOBALS] => Array
 *RECURSION*
    [my_global_var] => Hello World
)

Array
(
    [my_global_var] => Hello World
)

Example 6

Based on "@kainaw" answer I have updated Example 1 to help others understand what this would look like based on the examples given. Assume that nothing changed in "global_vars.php", but that in the "index.php" file the global statement preceded the include statement. It is then that "my_gloval_var" is considered by PHP to be a global variable, and initialized as such.

#global_vars.php
<?
$my_global_var = "Hello World";
?>

#index.php
<?
function foo ()
{
   global $my_global_var;

   include_once ("global_vars.php");

   print ("my global var = [" . $my_global_var . "]<BR>");
   print ("complete<BR>");
}

foo ();
?>

which outputs:

my global var = [Hello World] 
complete

The $GLOBALS and Define Vars return the following:

my global var = [Hello World]

Array
(
    [_GET] => Array ()
    [_POST] => Array ()
    [_COOKIE] => Array  ( ... )
    [_FILES] => Array ()
    [GLOBALS] => Array
 *RECURSION*
    [my_global_var] => Hello World
)

Array
(
    [my_global_var] => Hello World
)
  • 写回答

1条回答 默认 最新

  • dongshi8425 2014-12-31 19:30
    关注

    The main issue you have is a misunderstanding of what happens when you use the "global" command. This simplifies it:

    function foo()
    {
        $x = 1; // $x is local to foo() with a value of 1
        global $x; // $x is now the global (undeclared) variable
        echo $x; // Echos null
    }
    

    That is what happened in your first example. You set a variable and then switched that variable name to an undeclared global variable. Simple solution:

    function foo()
    {
        global $x; // $x is the global (undeclared) variable
        $x = 1; // $x (the global) now has a value of 1
        echo $x; // Echos 1
    }
    foo(); // Runs foo an echos 1.
    echo $x; // Also echos 1 because global $x is 1.
    

    The question of is it proper to declare globals inside a function is a different matter all together. This is simply to answer your question of the "strange" behavior. Personally, I register globals in the $GLOBALS array and use that as necessary.

    评论

报告相同问题?

悬赏问题

  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?