學過c的人用php的時候一般會相當順手,而且感到php太方便太輕鬆。但在變數作用域這方面卻與
c有不同的地方,搞不好會相當鬱悶,就找不到錯誤所在。昨晚就與到這麼乙個問題,是全域性變數在函式中的問題。今天搜尋了一下,發現一篇相當不錯的文章,講了php中的變數作用域。是一位網友翻譯的 在這貼一下:
變數的範圍即它定義的上下文背景(譯者:說白了,也就是它的生效範圍)。大部分的php變數只有乙個單獨的範圍。這個單獨的範圍跨度同樣包含了 include 和 require 引入的檔案。範例:
<?php
$a = 1;
include
"b.inc"
;?>
這裡變數$a 將會在包含檔案 b.inc 中生效。但是,在使用者自定義函式中,乙個區域性函式範圍將被引入。任何用於函式內部的變數按預設情況將被限制在區域性函式範圍內。範例:
<?php
$a = 1;
/* global scope */
function
test
()test
();?>
這個指令碼不會有任何輸出,因為 echo 語句引用了乙個區域性版本的變數$a,而且在這個範圍內,它並沒有被賦值。你可能注意到php的全域性變數和 c 語言有一點點不同,在 c 語言中,全域性變數在函式中自動生效,除非被區域性變數覆蓋。這可能引起一些問題,有些人可能漫不經心的改變乙個全域性變數。php中全域性變數在函式中使用時必須申明為全域性。
首先,乙個使用 global 的例子:
例子 12-1. 使用 global
<?php
$a = 1;
$b = 2;
function
sum()
sum();
echo $b;
?>
以上指令碼的輸出將是 "3"。在函式中申明了全域性變數$a 和 $b,任何變數的所有引用變數都會指向到全域性變數。對於乙個函式能夠申明的全域性變數的最大個數,php沒有限制。
在全域性範圍內訪問變數的第二個辦法,是用特殊的php自定義 $globals 陣列。前面的例子可以寫成:
例子 12-2. 使用 $globals 替代 global
<?php
$a = 1;
$b = 2;
function
sum()
sum();
echo $b;
?>
在 $globals 陣列中,每乙個變數為乙個元素,鍵名對應變數名,值變數的內容。$globals 之所以在全域性範圍內存在,是因為 $globals 是乙個超全域性變數。以下範例顯示了超全域性變數的用處:
例子 12-3. 演示超全域性變數和作用域的例子
<?php
function
test_global
()?>
變數範圍的另乙個重要特性是靜態變數(static variable)。靜態變數僅在區域性函式域中存在,但當程式執行離開此作用域時,其值並不丟失。看看下面的例子:
例子 12-4. 演示需要靜態變數的例子
<?php
function
test
()?>
本函式沒什麼用處,因為每次呼叫時都會將 $a 的值設為 0 並輸出 "0"。將變數加一的 $a++ 沒有作用,因為一旦退出本函式則變數$a 就不存在了。要寫乙個不會丟失本次計數值的計數函式,要將變數$a 定義為靜態的:
例子 12-5. 使用靜態變數的例子
<?php
function
test
()?>
現在,每次呼叫 test() 函式都會輸出 $a 的值並加一。
靜態變數也提供了一種處理遞迴函式的方法。遞迴函式是一種呼叫自己的函式。寫遞迴函式時要小心,因為可能會無窮遞迴下去。必須確保有充分的方法來中止遞迴。一下這個簡單的函式遞迴計數到 10,使用靜態變數$count 來判斷何時停止:
例子 12-6. 靜態變數與遞迴函式
<?php
function
test
()$count
--;}
?>
注:靜態變數可以按照上面的例子宣告。如果在宣告中用表示式的結果對其賦值會導致解析錯誤。例子 12-7. 宣告靜態變數
<?php
function
foo()
?>
在 zend 引擎 1 代,驅動了 php4,對於變數的 static 和 global 定義是以 references 的方式實現的。例如,在乙個函式域內部用 global 語句匯入的乙個真正的全域性變數實際上是建立了乙個到全域性變數的引用。這有可能導致預料之外的行為,如以下例子所演示的:
<?php
function
test_global_ref
() function
test_global_noref
() test_global_ref
();var_dump
($obj
);test_global_noref
();var_dump
($obj
);?>
執行以上例子會導致如下輸出:
nullobject(stdclass)(0)
類似的行為也適用於 static 語句。引用並不是靜態地儲存的:
<?php
function &
get_instance_ref
() $obj
->
property
++;return
$obj;}
function &
get_instance_noref
() $obj
->
property
++;return
$obj;}
$obj1
= get_instance_ref
();$still_obj1
= get_instance_ref
();echo
"/n"
;$obj2
= get_instance_noref
();$still_obj2
= get_instance_noref
();?>
執行以上例子會導致如下輸出:
static object: nullstatic object: null
static object: null
static object: object(stdclass)(1)
上例演示了當把乙個引用賦值給乙個靜態變數時,第二次呼叫 &get_instance_ref() 函式時其值並沒有被記住。
php變數作用域
1 在php中變數主要有 內建超級全域性變數,一般的變數,常量,全域性變數,靜態變數等。內建超級全域性變數 可以在指令碼的任何地方使用和可見。即如果我們在乙個php頁面中改變了其中的乙個值,那麼在其他php頁面中使用時,它的值也會發生改變。常量 一旦被宣告將可以在全域性可見,也就是說,它們可以函式內...
php變數作用域
先引入官網的一句話 變數的範圍即它定義的上下文背景 也就是它的生效範圍 大部分的 php 變數只有乙個單獨的範圍。這個單獨的範圍跨度同樣包含了 include 和 require 引入的檔案。我理解的就是 php變數只有乙個單獨範圍就是指函式內變數的範圍單獨作用於函式內部,函式外部的變數作用域只在函...
PHP變數作用域
php變數的4個作用域 在php指令碼的任何位置都可以宣告變數,但是,宣告變數的位置會大大影響訪問變數的範圍。這個可以訪問的範圍稱為作用域scope。php變數有4種作用域 區域性變數 在函式內部宣告的變數就是區域性變數,它儲存在記憶體的棧中,所以速度很快。區域性變數很有用,因為它消除了出線意外 的...