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

时间:2014-12-31 19:18:02

标签: php variables scope

关于适当的全局变量的使用有很多,我即将要求进一步澄清。许多可追溯到3年前的帖子都要求,"如何将变量包含在函数中,全局范围内。"

我的假设是他们的代码看起来像这样,因为没有给出明确的例子:

示例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 ();
?>

输出:

my global var = [] 
complete

示例2

现在,如果&#34; globals_var.php&#34;改为:

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

结果是:

my global var = [Hello World]
complete

示例3

现在,在您编写并声明不建议使用此类全局变量之前,有全局变量的实际用途。并且大多数全局变量作为常量或函数封装在对象中:

#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 ();
?>

输出结果为:

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

示例4

当然,此时&#34; include_once&#34;语句可以移到函数之外以获得相同的结果。

#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 ();
?>

输出:

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

示例5

在此示例中,文件包含在函数外部。一切都按照PHP.net文档的说明工作。

#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 ();
?>

问题......

现在我的问题......如果没有命名空间,为什么示例1中包含的变量不能放在$ GLOBALS中?而且,为什么这些变量不被视为功能范围的一部分?这里发生了什么?

示例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 ();
?>

输出结果为:

my global var = []

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

Array
(
    [my_global_var] => 
)

示例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
)

示例6

基于&#34; @ kainaw&#34;回答我已经更新了示例1,以帮助其他人根据给出的示例了解这将是什么样子。假设&#34; global_vars.php&#34;中没有任何变化,但是&#34; index.php&#34;在include语句之前提交全局语句。那就是&#34; my_gloval_var&#34;被PHP认为是一个全局变量,并按原样初始化。

#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 ();
?>

输出:

my global var = [Hello World] 
complete

$ GLOBALS和Define 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
)

1 个答案:

答案 0 :(得分:2)

您遇到的主要问题是对使用“全局”命令时会发生什么的误解。这简化了它:

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
}

这就是你的第一个例子。您设置一个变量,然后将该变量名称切换为未声明的全局变量。简单的解决方案:

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.

在函数内声明全局变量是否合适是一个问题。这只是回答你关于“奇怪”行为的问题。就个人而言,我在$ GLOBALS数组中注册全局变量并在必要时使用它。