PHP 的全域變數和C 語言有一點點不同,在C 語言中,全域變數在函數中自動生效,除非被局部變數覆蓋
這可能會引起一些問題,有些人可能漫不經心的改變一個全域變數。 PHP 中全域變數在函數中使用時必須申明為全域(注意,Global這個關鍵字在函數中定義才有用)。
1:Global的作用是定義全域變數,但是這個全域變數不是應用於整個網站,而是應用於目前頁面,包括include或require的所有檔案。
<?PHP $a=123; function aa() {
Global $a; //如果不把$a定義為global變數,函數體內是不能存取函數體外部的$a的,但是可以定義一個相同的名字$a,此時這個變數是局部變量,等同於C語言的局部變量,只能在函數體內部使用。
echo $a; } aa(); ?>
總結:在函數體內定義的global變數,函數體外可以使用,在函數體外定義的global變數不能在函數體內使用,
$global $a; $a=123; function f() { echo $a; //错误, }
#//再看看下面一個例子
function f() { global $a; $a=123; } f();
echo $a; //正確,可以使用
2:global問題解析:
question:我在config.inc.php中定義了一些變數($a),在別的檔案中函數外部include("config.inc.php"),函數內部需要使用這些變數$a,如果沒有聲明的話,echo $a是印不出來任何東西的。因此聲明global $a,但是有很多函數和很多變量,總不能不斷重複的這樣聲明吧?有什麼好的解決辦法,請指著一點。
answer1:先在config.inc.php裡定義常數:define(常數名,常數值)
再在其他需要用到的地方require 'config.inc.php',
#然後就能在這個文件裡直接使用這個常數了。
answer2:我也有辦法,就是定義數組,如$x[a],$x,那樣就只要宣告global $x一個了。
answer3:我試了你的這個方法,不行啊。
answer4:改變你的php.ini檔。
3.一些Global和$GLOBALS 陣列的範例
範例:使用 global
<?PHP $w3sky = 1; $w3sky2 = 2; function Sum() { global $w3sky, $w3sky2;$w3sky2 = $w3sky + $w3sky2; }Sum(); echo $w3sky2; ?>
以上腳本的輸出將是「3」。在函數中申明了全域變數 $w3sky 和 $w3sky2,任何變數的所有引用變數都會指向到全域變數。對於函數能夠申明的全域變數的最大個數,PHP 沒有限制。
在全域範圍內存取變數的第二個方法,是用特殊的 PHP 自訂 $GLOBALS 陣列。前面的例子可以寫成:
範例 使用 $GLOBALS 取代 global
<?PHP $w3sky = 1; $w3sky2 = 2;function Sum() { $GLOBALS['w3sky'] = $GLOBALS['w3sky'] + $GLOBALS['w3sky2']; }Sum(); echo $w3sky2; ?>
在 $GLOBALS 陣列中,每一個變數為一個元素,鍵名對應變數名,值對應變數的內容。 $GLOBALS 之所以在全域範圍內存在,是因為 $GLOBALS 是一個超全域變數。以下範例顯示了超全域變數的用處:
範例示範超全域變數和作用域的範例
<?PHP function test_global() { // 大多数的预定义变量并不 "super",它们需要用 'global' 关键字来使它们在函数的本地区域中有效。 global $HTTP_POST_VARS;echo $HTTP_POST_VARS['name'];// Superglobals 在任何范围内都有效,它们并不需要 'global' 声明。Superglobals 是在 PHP 4.1.0 引入的。 echo $_POST['name']; } ?>
global 也就是說是在一個檔案裡只要你宣告為global $db 那麼在宣告的下面你就可以引用這個$db了。
4.原來以為global和$GLOBALS除了寫法不一樣以為,其他都一樣,可是在實際應用中發現,2者的區別還是很大的!
先看下面的例子:
<?php // 例子1 function test_global() { global $var1, $var2; $var2 =& $var1; } function test_globals() { $GLOBALS['var3'] =& $GLOBALS['var1']; } $var1 = 5; $var2 = $var3 = 0; test_global(); print $var2 ."\n"; test_globals(); print $var3 ."\n"; ?>
複製程式碼
執行結果為:
0
5
怎麼會這樣呢?不應該是2個5嗎?怎麼會出現1個0和1個5呢?
恩,我們保留以上問題,深入分析$GLOBALS和global的原理!
我們都知道變數其實是相應物理內存在代碼中的"代號",假設我們上面聲明的3個變數分配的記憶體如下圖表示:
引用php手冊的$GLOBALS的解釋:
Global 變數:$GLOBALS
注意: $GLOBALS 在PHP 3.0.0 及以後版本適用。
由所有已定義全域變數所組成的陣列。變數名就是該數組的索引。
這是一個“superglobal”,或可以描述為自動全域變數。
也就是說上面程式碼中的$var1和$GLOBALS['var1']是指的相同變量,而不是2個不同的變數!
下面來分析global到底做了什麼?
我們都知道php中的函數所產生的變數都是函數的私有變量,那麼global關鍵字產生的變數也一定逃不出這個規則,為什麼這麼說呢,看下面的程式碼:
<?php // 例子2 function test() { global $a; unset($a); } $a = 1; test(); print $a; ?>
执行结果为:
1
为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?
都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数后面加入
print $a;
复制代码
来测试!也就是说global产生了test函数外部$a的别名变量“$a”,为了和外面的$a区别,我把它成为--test->$a,那么例子1也这么命名的话,可得出下面的图:
而test_globals执行过以后,看变量的变化:
此时,看图,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!
所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:
global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况(为什么会打印结果为2呢?其实就是因为$var1的引用指向了$var2的引用地址。导致实质的值没有改变。这时候只是指向$var1的指针指向了$var2的指针,只是指针指向变了一下,但是实质上根本就没有改变$var2的值,因此$var2的值仍旧不会变化),例如例子1.
$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致!
注:(接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化只在函数的局部产生效应,在函数外部$var2的指向物理内存地址并没有变化,还是它自己.(重点)
接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化由下图可以看出)
以上是php中global和$GLOBALS[]的實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!