1. 程式人生 > >引用變數(&)

引用變數(&)

參考:
PHP引用的官方解釋

摘要:
引用變數概念:不同的名字訪問同一個變數內容
引用變數的定義方式:使用&符號
引用變數的優點:大陣列使用引用能夠節省大量的記憶體;引用可以寫出簡潔的程式碼;

一、引用變數基礎知識

Demo1 使用memory_get_usage函數了解引用

//定義一個變數
$a = range(0, 1000);
var_dump(memory_get_usage());//該函式檢視記憶體的使用情況

//定義變數b,將a變數的值賦值給b
//引用變數不存在 COW原則(Copy On Write,該原則是:一個變數賦值給一個引數,這個引數賦值給另一個引數,只有第二個引數發生改變時才會在記憶體當中重新生成一塊記憶體)
$b = &$a;
var_dump(memory_get_usage());

//對 a進行修改
$a = range(0, 1000);
var_dump(memory_get_usage());

//結果:記憶體的使用兩都是差不多的,說明並沒有使用新的空間來儲存

圖形解釋:
在這裡插入圖片描述

Demo2 使用xdebug_debug_zval函數了解引用

// zval變數容器
$a = range(0, 3);
xdebug_debug_zval('a');//檢視變數在記憶體當中的引用資訊(該函式有兩個引數:refcount變數引用的數量、is_ref是否被引用;該函式的使用需要安裝xdebug擴充套件,Linux需要yum進行安裝)

$b = &$a;
xdebug_debug_zval('a');

$a = range(0, 3);
xdebug_debug_zval('a');

列印的結果:
在這裡插入圖片描述

Demo3 引用變數的銷燬

// unset 只會取消引用,不會銷燬引用
$a = 1;

$b = &$a;

unset($b);

echo $a. "\n";

圖形解釋:
在這裡插入圖片描述

二、物件與引用的關係

物件本身就是引用傳值,所以就不用使用&
Demo4 物件與引用變數

// 物件本身就是引用傳遞
class Person
{
	public $name = "zhangsan";
}

$p1 = new Person;
xdebug_debug_zval('p1');

$p2 = $p1;
xdebug_debug_zval('p1');

$p2->name = "lisi";
xdebug_debug_zval('p1');

在這裡插入圖片描述

三、引用變數的經典題

ps:這道題一定是你似曾相識的問題

// 寫出如下程式的輸出結果
$data = ['a', 'b', 'c'];
foreach ($data as $key => $value) {
	$val = &$data[$key];
}
//程式執行時,每一次迴圈結束後變數$data的值是什麼?請解釋
//程式執行完成後,變數$data的值是什麼?請解釋

注:引用變數在引用地址發生改變時,原來的變數會保持原來的引用的值,相對而言只是失去了引用;