所謂PHP的引用,就是不同的名字存取同一個變數內容。可用在變數、函數以及物件上,用法就是在它們前面加上&符號。以下來細說下引用的類型與功能:
一、引用類型
1.1、變數引用: 兩個變數指向同一個內容
Php
<?php $a = "abc"; $b = &$a; echo $a;//这里输出:abc echo $b;//这里输出:abc $b = "done"; echo $a;//这里$a的值变为done, 所以输出done echo $b;//这里输出done ?>
程式碼
function test(&$a) { $a=$a+100; } $b=1; test($b); //这里$b传递给函数的其实是$b的变量内容所处的内存地址,通过在函数里改变$a的值,就可以改变$b的值了 echo $b;//输出101要注意的是,在這裡test(1); 的話就會出錯,原因自己去想 1.3、函數引用
Php代碼 $ ()方式呼叫函數,只是將函數的值賦給$a而已, 而$a做任何改變都不會影響到函數中的$b, 而透過$a=&test()方式調用函數呢, 他的作用是將return $b中的$b變數的記憶體位址與$a變數的記憶體位址指向了同一個地方, 即產生了相當於這樣的效果($a=&b;) 所以改變$a的值, 也同時改變了$b的值, 所以在執行了
$a=5;
以後,$b的值變為了5
這裡是為了方便理解函數的引用返回才使用靜態變量,其實函數的引用回傳多用在物件中
1.4、物件的引用
Php程式碼
function &test() { static $b=0;//申明一个静态变量 $b=$b+1; echo $b; return $b; } $a=test();//$b的值:1 $a=5; $a=test();//$b的值:2 $a=&test();//$b的值:3 $a=5; $a=test();//$b的值:6
class testa { var $abc="ABC"; } $b=new testa; $c = &$b; // or $c = $b; echo $b->abc;//这里输出ABC echo $c->abc;//这里输出ABC $b->abc="DEF"; echo $c->abc;//这里输出DEF以上程式碼是在PHP5中的效果量;是透過引用來實現的。上例中$b=new a; $c=$b; 其實等效於$b=new a; $c=&$b;
PHP5中預設就是透過引用來呼叫對象, 但有時你可能會想建立一個物件的副本,並希望原來的物件的改變不影響副本。 為了這樣的目的,PHP定義了一個特殊的方法,稱為__clone.
二、引用的作用
如果程序比較大,引用同一個對象的變量比較多,並且希望用完該對象後手工清除它,個人建議用"&" 方式,然後用$var=null的方式清除。其它時候還是用php5的預設方式吧。另外, php5中對於大數組的傳遞,建議用 "&" 方式, 畢竟節省記憶體空間使用。
三、取消引用
當你 unset 一個引用,只是斷開了變數名稱和變數內容之間的綁定。這並不意味著變數內容被銷毀了。例如:
<?php $a = 1; $b =& $a; unset ($a); ?>不會 unset $b,只是毀了 $a。
再如global 引用,當用 global $var 宣告一個變數時實際上建立了一個到全域變數的引用。也就是說和這樣做是相同的:
<?php $var =& $GLOBALS["var"]; ?>
這意味著,例如,unset $var 不會 unset 全域變數。
$this 的引用:在一個物件的方法中,$this 永遠是呼叫它的物件的引用。
PS:
PHP有個好處就是可利用其擁有的自動垃圾回收機制(釋放記憶體)。即不需要在使用完變數後做任何釋放記憶體的處理,PHP會幫你完成。當然,我們可以按自己的意願呼叫 unset() 函數來釋放內存,但通常不需要這麼做。
如果兩個對象之間存在著相互引用的關係,如“父對象-子對象”,對父物件呼叫unset()不會釋放在子物件中引用父物件的記憶體(即便父物件被垃圾回收,也不行)。
這個時候,即便是手動呼叫 unset()。詳情可考:http://bugs.php.net/bug.php?id=33595 。
補充:
1:如果有下面的代碼
$a="ABC";
$b=$a;
其實此時,$a與$b都是指向同一內存地址,而並不是指$a與$b佔用不同的記憶體
2:如果在上面的程式碼基礎上加上如下程式碼
$a="EFG";
由於$a與$b所指向的記憶體的資料要重新寫一次了,此時Zend核心會自動判斷,自動為$b生產一個$a的資料拷貝,重新申請一塊記憶體進行儲存。