變數的範圍只是在其所定義的空間內存在。在大部份的情況下,PHP 的變數只有一個單一的範圍。這單一的範圍也包含了以 include 和 require 方式引入的檔案。例如:
例子中,變數 $a 也存在于被包含入的程式 b.inc 中。但是在使用者自訂的函數中,一個區域性的函數範圍將被引用。任何在函數內使用的變數在預設的情況下只局限於該函數的範圍內。例如:
<?php |
這個程式不會輸出任何東西,因為 echo 述句使用了本區域版本的 $a 變數,而該本區域變數並未曾被分配一個值。你會發現這和 C 語言的做法不同,因為 C 的全域變數是自動的提供給各函數,除非在本域定義中指明撤銷。此做法可能會引致一些問題,如使用者不慎地更改了全域變數的值。在 PHP 中,全域變數在本域使用前必須先宣佈為全域。例子:
上述例子將會輸出 "3"。在函數內宣佈 $a 及 $b 為全域後,所有涉及該兩個變數的使用將自動指向全域的版本。PHP 沒有限定一個函數可以使用的全域變數的數量。
第二種存取全域範圍中的變數方法是使用一個由 PHP 特別定義的陳列:$GLOBALS。前面的例子可以重寫為:
$GLOBALS 是一個關聯陳列 (associative array),全域變數的名即為索引鍵,而該變數的內容即為陳列的值。有否留意到 $GLOBALS 在任何一個範圍都出現?那是因為 $GLOBALS 是一個superglobal。這是一個示範 superglobals 強大功能的例子:
<?php |
變數範圍的另一個重要功能為靜態變數。靜態變數只在本域函數範圍內存在,但是當程式執行離開此範圍時,它並不會喪失它的值。看看下面的例子:
此函數沒有什麼用處,因每一次執行它時,它將 $a 設為 0 然後列印出 "0"。$a++ 增加了 $a 的值,但並沒有實際用途因為一旦離開了該函數,變數 $a 也隨之消失。要設計一個有用的、不會丟失當前計數的計數函數,我們可以將 $a宣佈為靜態:
現在,每當函數 Test() 被呼叫時,它會列印出 $a 的值,然後加上一。
靜態變數也提供一種處理遞迴函數的方法。遞迴函數是一種呼叫自己的函數。編寫遞迴函數時必須留意,因為若編寫錯誤,它有可能會無定限地遞迴。您必須確定足夠的方式來終止遞迴。下列簡單的函數將遞迴地數到 10,利用靜態變數 $count 來斷定什麼時候停止:
<?php |
驅動 PHP 4 的 Zend Engine 1 是以參照的方式來實現 static 和 global 的。例如,一個真正的全域變數使用 global 方式引進一個函數範圍時實際上就是建立了一個全域變數的參照。這將導致一些意想不到的行為,正如下列例子所述:
<?php |
執行這個例子將會導致下列的輸出:
NULL object(stdClass)(0) { } |
static 陳述式也會導致同樣的輸出。參照並沒有被靜態地儲存:
<?php |
執行此例子將導致下列的輸出:
Static object: NULL Static object: NULL Static object: NULL Static object: object(stdClass)(1) { ["property"]=> int(1) } |
上述例子示範了在指派一個參照給予一個靜態變數後,當您第二次呼叫 &get_instance_ref() 函數時,它是不會記住之前的值的。