在 PHP 中引用是指用不一樣的名字訪問同一個變量內容。
PHP 中的變量名和變量內容是不同的, 所以一樣的內容能夠有不一樣的名字。
最接近的比喻是 Unix 的文件名和文件自己——變量名是目錄條目,而變量內容則是文件自己。引用能夠被看做是 Unix 文件系統中的硬連接。php
PHP 中的引用並不像 C 的指針:例如你不能對他們作指針運算。引用並非實際的內存地址,而是符號表別名。數組
$a =& $b;
這意味着 $a 和 $b 指向了同一個變量。函數
$a 和 $b 在這裏是徹底相同的,這並非 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一個地方。
$a = 'a'; $arr1 = [ 'a' => $a, 'b' => &$a, // $arr1['b'] 與 $a 指向同一個變量 ]; // 將 $arr1 傳值賦值給 $arr2 $arr2 = $arr1; print_r($arr2); // $arr2 的值爲 ['a' => 'a', 'b' => 'a'] // 修改 $a 的值爲 'b' $a = 'b'; print_r($arr2); // $arr2 的值爲 ['a' => 'a', 'b' => 'b'] function foo($arr){ // 將 $arr['b'] 的值改成 'c'; $arr['b'] = 'c'; } echo $a; // $a 的值爲 'b' // 將 $arr1 傳入函數 foo($arr1); echo $a; // $a 的值爲 'c'
// 定義函數 foo(),經過引用傳遞參數 function foo(&$var) { } foo($a); // 建立變量 $a,值爲 NULL var_dump($a); // NULL foo($b['b']); // 建立數組 $b = ['b' => NULL] var_dump(array_key_exists('b', $b)); // bool(true) $c = new StdClass; foo($c->d); // 建立對象屬性 $c->d = NULL var_dump(property_exists($c, 'd')); // bool(true)
$var1 = 'var1'; $var2 = 'var2'; function global_references($use_globals) { global $var1, $var2; if (!$use_globals) { $var2 = & $var1; // $var2 只在函數內部可見 } else { $GLOBALS["var2"] = & $var1; // $GLOBALS["var2"]在全球範圍內也可見 } } global_references(false); echo "var2 is set to '$var2'\n"; // var2 is set to 'var2' global_references(true); echo "var2 is set to '$var2'\n"; // var2 is set to 'var1'
能夠把 global $var;
當成是 $var =& $GLOBALS['var'];
的簡寫。從而將其它引用賦給 $var 只改變了本地變量的引用。性能
$ref = 0; $row = & $ref; foreach ([1, 2, 3] as $row) { // do something } echo $ref; // 3 - 遍歷數組的最後一個元素
function foo(&$var) { $var++; } $a=5; foo($a); echo $a; // 6
注意在函數調用時沒有引用符號——只有函數定義中有。光是函數定義就足夠使參數經過引用來正確傳遞了。優化
function foo(&$var) { $var++; } $a=5; foo($a); echo $a; // 6
function foo(&$var) { $var++; echo $var; // 6 } function &bar() { $a = 5; return $a; } foo(bar());
function foo(&$var) { $var++; } function bar() // 注意,這個函數不返回引用 { $a = 5; return $a; } foo(bar()); // 自 PHP 5.0.5 起致使致命錯誤,自 PHP 5.1.1 起致使嚴格模式錯誤,自 PHP 7.0 起致使 notice 信息 foo($a = 5); // 表達式,不是變量。PHP Notice: Only variables should be passed by reference foo(5); // PHP Fatal error: Only variables can be passed by reference
當你想要使用一個函數來找到一個引用應該被綁定的變量時,可使用引用返回。
不要用返回引用來增長性能,引擎足夠聰明,能夠本身進行優化。僅在有合理的技術緣由時才返回引用!this
class Foo { public $value = 42; public function &getValue() { return $this->value; } } $foo = new Foo; // $myValue 是 $obj->value 的引用. $myValue = &$foo->getValue(); // 將 $foo->value 修改成 2 $foo->value = 2; echo $myValue; // 2
與參數引用傳遞不一樣,引用返回必須在兩個地方都用 & 符號 —— 指出返回的是一個引用,而不是一般的一個拷貝,一樣也指出 $myValue 是做爲引用的綁定,而不是一般的賦值。
引用返回只能返回變量。若是試圖這樣從函數返回引用:return intval($this->value);
,將會報錯,由於函數在試圖返回一個表達式的結果而不是一個引用的變量。只能從函數返回引用變量——沒別的方法。指針
class Foo { public $value = 42; public function &getValue() { return intval($this->value); // PHP Notice: Only variable references should be returned by reference } } $foo = new Foo; // $myValue 是 $obj->value 的引用. $myValue = &$foo->getValue();
當 unset 一個引用,只是斷開了變量名和變量內容之間的綁定。這並不意味着變量內容被銷燬了。code
$a = 1; $b = & $a; unset($a); echo $b; // 1
許多 PHP 的語法結構是經過引用機制實現的,因此上述有關引用綁定的一切也都適用於這些結構。對象
當用 global $var
聲明一個變量時其實是在函數內部創建了一個到全局變量的引用。也就是說這樣作的效果是相同的:內存
global $var; $var =& $GLOBALS["var"];
這意味着,unset $var
不會 unset 掉全局變量 $GLOBALS["var"]
。
在一個對象的方法中,$this 永遠是調用它的對象的引用。