曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 4569|回复: 0
打印 上一主题 下一主题

变量的作用域,global 与 GLOBALS 的异同

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2012-6-14 17:49:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一般情况下,PHP 变量只有单一的作用范围,即它处于它所被定义的上下文中。如果要跨越这个当前范围,那么可以使用 include 或者 require 进行包含。比如有两个文件 a.php 和 b.php,其中 a.php 的内容为:
[Plain Text] 纯文本查看 复制代码
<?php
        $a = 'groad.net';
        include 'b.php';
?>

b.php 的内容为:
[Plain Text] 纯文本查看 复制代码
<?php
    echo $a;
?>

在 a.php 中,使用 include 对 b.php 进行包含,这样一来, b.php 就可以“看得到” a.php 中定义的变量 $a,并且执行 echo 的输出,如:


当然,这样 include 进来的 b.php 中若有定义变量,那么在 a.php 中也是可见的。

函数中的变量与全局变量( global 关键字, $GLOBALS 数组)
如果使用过 C 语言,那么会知道,全局变量可以在函数中直接使用,除非全局变量和函数中的局部变量同名,那么使用的是局部变量,而不是使用全局变量。PHP 和 C 语言有点不一样,看下面的代码所示:
[PHP] 纯文本查看 复制代码
<?php
        $domain = 'groad.net';
        
function dnslookup()
{       
        echo $domain;
}       


dnslookup();


?>

上面函数不会有任何输出,这是因为作为全局变量的 $domain 不会传递到函数 dnslookup() 中。那么在函数中要想使用全局变量的值怎么办?方法是使用 global 关键字。修改上面代码如下:
[PHP] 纯文本查看 复制代码
<?php
        $domain = 'groad.net';
        $subdomain = 'www.groad.net';


function dnslookup()
{       
        global $domain, $subdomain;
        echo $domain . "<br>" . $subdomain;
}       


dnslookup();


?>

这下子可以正常使用全局变量了:



不使用 global 也可以,可以使用一个预定义的全局数组 $GLOBALS 来代替,修改上面的代码如下:
[C++] 纯文本查看 复制代码
<?php
        $domain = 'groad.net';
        $subdomain = 'www.groad.net';


function dnslookup()
{
        echo $GLOBALS['domain'] . "<br>" . $GLOBALS['subdomain'];
}


dnslookup();


?>

使用 $GLOBALS 数组和使用 global 同样的功效。

现在需要再来看一种特殊的情况。正如上面所看到的,global 可以使我们在函数内部使用外面定义的全局变量。但是,如果我们在函数内部使用一下引用 会发生什么情况呢?看下面代码:
[C++] 纯文本查看 复制代码
<?php


function tmp()
{
        global $var1, $var2;


        $var1 =& $var2;
        echo "In function tmp(), value of var1 is ". $var1;
        echo "<br>";


        $var1 = 180;
        echo "In function tmp(), value of var2 is ". $var2;
        echo "<br>";


}


$var1 = 10;
$var2 = 5;


tmp();


echo "In main function, value of var1 is " . $var1;
echo "<br>";
echo "In main function, value of var2 is " . $var2;


?>

输出结果有点出乎意料:


在 tmp() 函数中, $var1 =& $var2; 这条语句使 $var1 成为了 $var2 的引用,那么第 1 条的输出结果是理所当然的。当  $var1 = 180; 这条语句改变 $var1 的值是,也可以理解 $var2 的值也会随之改变。

当从 tmp() 函数回到主函数中时,我们也发现 $var2 的只值也随之改变了,这也很合理。但是奇怪的是,主函数中的 $var1 的值竟然还是 10,而不是 180 !这就说明了,tmp() 外和 tmp()内的 $var1 不是一个值!然而,如果我们在 tmp() 内不声明 $var1 作为 $var2 的引用时,那么我们若是在 tmp() 函数里改变 $var1 的值,则函数外的 $var1 的值也会随之改变,比如代码修改为:
[PHP] 纯文本查看 复制代码
<?php


function tmp()
{
        global $var1, $var2;
        $var1 = 180;
}


$var1 = 10;
$var2 = 5;


tmp();


echo "In main function, value of var1 is " . $var1;
?>

此时会输出:


像上面的现象,可以用 C 语言中的指针来说明,看下面的 C 代码:
[C++] 纯文本查看 复制代码
#include <stdio.h>


void tmp(int *v1, int *v2)
{
        int *p1 = v1;
        int *p2 = v2;


        *p1 = 180;
}


int main()
{
        int var1 = 10;
        int var2 = 5;


        tmp(&var1, &var2);


        printf ("%d\n", var1);


        return 0;
}

运行输出:
[beyes@beyes   varscope]$ ./test
180
嗯,这是一般情况,类似与在 tmp() 中改变了 $var1 的值,那么主函数中的 $var1 的值也随之改变。稍微修改一下上面的 C 代码,用来模拟上面的那种“奇怪”的情况(实际上并不是很奇怪):
[C++] 纯文本查看 复制代码
#include <stdio.h>


void tmp(int *v1, int *v2)
{
        int *p1 = v1;
        int *p2 = v2;




        p1 = p2;
        printf ("In function tmp(), value of var1 is %d\n", *p1);


        *p1 = 180;
        printf ("In function tmp(), value of var2 is %d\n", *p2);


}


int main()
{
        int var1 = 10;
        int var2 = 5;


        tmp(&var1, &var2);


        printf ("In main function, value of var1 is %d\n", var1);
        printf ("In main function, value of var2 is %d\n", var2);


        return 0;
}

运行输出:
[beyes@beyes   varscope]$ ./test
In function tmp(), value of var1 is 5
In function tmp(), value of var2 is 180
In main function, value of var1 is 10
In main function, value of var2 is 180
对比 PHP 代码和 C 代码,那么就容易理解上面的结果了。

global 与 GLOBALS 不同的是,GLOBALS 是被称为  Superglobals 的超级全局变量,实际上就相当于 C 语言里的全局变量,它那是实实在在的操作变量本身。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-4-30 10:55 , Processed in 0.077587 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表