PHP 中一個美元符號后面跟上一個變量名稱,即表示一個變量。變量的名稱是對大小寫敏感的。變量名與 PHP 中其它的標(biāo)簽一樣遵循相同的規(guī)則。一個有效的變量名由字母或者下劃線開頭,后面跟上任意數(shù)量的字母,數(shù)字,或者下劃線。按照正常的正則表達(dá)式,它將被表述 為:'[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*’
AD:
全局和靜態(tài)變量的引用
在 Zend 引擎 1 代,驅(qū)動了 PHP4,對于變量的 static 和 global 定義是以 references 的方式實現(xiàn)的。例如,在一個函數(shù)域內(nèi)部用 global 語句導(dǎo)入的一個真正的全局變量實際上是建立了一個到全局變量的引用。這有可能導(dǎo)致預(yù)料之外的行為,如以下例子所演示的:
<?php function test_global_ref() { global $obj; $obj = &new stdclass; } function test_global_noref() { global $obj; $obj = new stdclass; } test_global_ref(); var_dump($obj); test_global_noref(); var_dump($obj); ?> |
執(zhí)行以上例子會導(dǎo)致如下輸出:
NULL object(stdClass)(0) { } |
類似的行為也適用于 static 語句。引用并不是靜態(tài)地存儲的:
<?php function &get_instance_ref() { static $obj; echo "Static object: "; var_dump($obj); if (!isset($obj)) { // 將一個引用賦值給靜態(tài)變量 $obj = &new stdclass; } $obj->property++; return $obj; } function &get_instance_noref() { static $obj; echo "Static object: "; var_dump($obj); if (!isset($obj)) { // 將一個對象賦值給靜態(tài)變量 $obj = new stdclass; } $obj->property++; return $obj; } $obj1 = get_instance_ref(); $still_obj1 = get_instance_ref(); echo "n"; $obj2 = get_instance_noref(); $still_obj2 = get_instance_noref(); ?> |
執(zhí)行以上例子會導(dǎo)致如下輸出:
Static object: NULL Static object: NULL Static object: NULL Static object: object(stdClass)(1) { ["property"]=> int(1) } |
上例演示了當(dāng)把一個引用賦值給一個靜態(tài)變量時,第二次調(diào)用&get_instance_ref() 函數(shù)時其值并沒有被記住。
可變變量
有時候使用可變變量名是很方便的。就是說,一個變量的變量名可以動態(tài)的設(shè)置和使用。一個普通的變量通過聲明來設(shè)置,例如:
?<php $a = "hello"; ?> |
一個可變變量獲取了一個普通變量的值作為這個可變變量的變量名。在上面的例子中 hello 使用了兩個美元符號($)以后,就可以作為一個可變變量的變量了。例如:
<?php $$a = "world"; ?> |
這時,兩個變量都被定義了:$a 的內(nèi)容是“hello”并且 $hello 的內(nèi)容是“world”。因此,可以表述為:
<?php echo "$a ${$a}"; ?> |
以下寫法更準(zhǔn)確并且會輸出同樣的結(jié)果:
<?php echo "$a $hello"; ?> |
它們都會輸出:hello world。
要將可變變量用于數(shù)組,必須解決一個模棱兩可的問題。這就是當(dāng)寫下 $$a[1] 時,解析器需要知道是想要 $a[1] 作為一個變量呢,還是想要 $$a 作為一個變量并取出該變量中索引為 [1] 的值。解決此問題的語法是,對第一種情況用 ${$a[1]},對第二種情況用 ${$a}[1]。
注意可變變量不能用于 PHP 的超全局變量數(shù)組。這意味著不能這樣用:${$_GET}。 如果想要一種處理超全局變量和老的 HTTP_*_VARS 的方法,應(yīng)該嘗試引用它們。