前言
程式 (program) 運行時,會將使用的資料 (data) 存在記憶體中。變數本身不是資料,而是指向資料的標籤。本文介紹 PHP 的變數。
宣告變數
PHP 的變數是大小寫敏感的。其命名規則如下:
- 前綴使用
$
(dollar sign) - 首字使用英文字或底線
- 接下來使用英文字、阿拉伯數字或底線
- 不能用保留字 (keyword) 來命名變數
但 PHP 沒有 Perl 的變數前綴 (sigil) 規則,所有的變數前綴皆為 $
。
參考 (Reference)
參考會指向特定變數所指向的記憶體。修改參考可間接修改變數的值。像是以下例子:
<?php
$foo = 3;
$bar = &$foo;
$bar = 10;
10 == $foo or die("Wrong number");
在這個例子中,由於變數 $bar
是指向變數 $foo
的參考,修改 $bar
時,會間接修改 $foo
。
內建變數 (Predefined Variables)
PHP 有許多預先定義好的內建變數,這些變數可在 PHP 程式中立即使用。內建變數有一大部分和撰寫網頁程式相關。這裡有一份 PHP 內建變數的清單,讀者可以邊寫邊查,久了就會熟悉 PHP 的內建變數。
變數的可視域 (Scope)
理解變數的可視域相當重要,有時候一些不顯著的 bug 就是未能理解可視域所造成。本節介紹 PHP 變數的可視域。
一般情境
PHP 變數僅有單一可視域。也就是說,PHP 變數沒有區塊的概念。這項特性類似於 JavaScript 而和 C 相異。
例如,以下程式執行空的 for
迴圈,在程式執行後變數 $i
仍然存在:
<?php
for ($i = 1; $i <= 10; ++$i) {}
# Oops!
is_null($i) or die("\$i is available\n");
這是因為 PHP 沒有為 for
迴圈建立獨立的可視域,所以 for
迴圈結束後,變數 $i
仍然存在。
函式具有獨立的可視域
如果真在要建立獨立的可視域的話,可以使用 IIFE (立即執行函式) 模式:
<?php
# IIFE pattern in PHP 7+.
(function () {
for ($i = 1; $i <= 10; ++$i) {}
})();
is_null($i) or die("\$i is available\n");
技術上來說,這個程式建立一個匿名函式 (anonymous function)。該函式建立完後立即執行。
實際上 PHP 程式甚少使用 IIFE 模式,比較簡單的方式是每次要使用變數前都確實地賦值,就不需在意該變數先前是否有使用過。
global
變數
由於函式有獨立的可視域,以下程式不會照預想的方式來執行:
<?php
$a = 3;
$b = 4;
function sum()
{
return $a + $b;
}
# Oops!
7 == sum() or die("Wrong value");
這是因為函式的可視域是獨立的,不會讀入 $a
和 $b
。
如果想在函式中讀入外部變數,可使用保留字 global
:
<?php
$a = 3;
$b = 4;
function sum()
{
global $a, $b;
return $a + $b;
}
7 == sum() or die("Wrong value");
這時候函式會讀入 $a
和 $b
,如同原本預期的情形。
static
變數
每次函式執行時,內部狀態會重新運算。若想在函式呼叫時儲存其狀態,可使用保留字 static
。
以下範例函式 fib
內的變數 $a
和 $b
會在每次函式執行後儲存下來。所以每次回傳值皆相異:
<?php
# Fibonacci numbers.
function fib()
{
static $a = 1, $b = 1;
$result = $a;
$c = $a + $b;
$a = $b;
$b = $c;
return $result;
}
for ($i = 0; $i < 20; ++$i) {
echo fib() . "\n";
}
這個程式利用這項特性來進行 Fibonacci 數的計算。
超全域變數 (Superglobal)
超全域變數是在所有 PHP 程式中都可以存取的變數。程式設計者無法在 PHP 程式中建立新的超全域變數。替代的方式是在 $GLOBALS
陣列中建立屬性。$GLOBAL
本身是 PHP 內建變數。其屬性在 PHP 程式中任一處皆可存取,不讀是函式內還是函式外。
在 $GLOBALS
中建立屬性的方式如下:
$GLOBALS["foo"] = 12345;
之後,讀入 $GLOBALS["foo"]
即可取得其值。
從外部來源取得的變數
這和網頁程式相關。像是 $_GET
和 $_POST
陣列包含 HTML 表單送出的變數,$_COOKIE
陣列包含 cookie 儲存的變數。
宣告常數 (Constant)
內建函式 define
可用來宣告常數。常數在宣告後就不會再改變。試圖修改常數會引發程式錯誤。常數沒有前綴 $
。
以下 PHP 程式宣告圓周率:
define("PI", 3.1415927);
內建常數 (Predefined Constant)
PHP 提供多個內建常數,這些常數可以在程式中直接使用。這裡有一份內建常數的清單。讀者可以邊寫邊查,自然而然地熟悉這些常數。
魔術常數 (Magic Constant)
魔術常數提供和程式相關的資料。這些常數會根據情境,在編譯期自動轉成相對應的資料。以下是 PHP 的魔術常數:
__LINE__
:在程式中的行數__FILE__
:檔案的路徑和檔名__DIR__
:檔案所在的目錄__FUNCTION__
:目前的函式名稱__CLASS__
:目前的類別名稱__TRAIT__
:目前的 trait 名稱__METHOD__
:目前的方法 (method) 名稱__NAMESPACE__
:目前的命名空間 (namespace)ClassName::class
:類別的全名