引用是什么
在 PHP 中引用意味著用不同的名字訪問同一個(gè)變量內(nèi)容,這并不像 C 的指針,替代的是,引用是符號(hào)表別名,注意在 PHP 中,變量名和變量內(nèi)容是不一樣的,因此同樣的內(nèi)容可以有不同的名字,最接近的比喻是 Unix 的文件名和文件本身——變量名是目錄條目,而變量內(nèi)容則是文件本身,引用可以被看作是 Unix 文件系統(tǒng)中的 hardlink。
引用做什么
PHP 的引用允許用兩個(gè)變量來指向同一個(gè)內(nèi)容。
當(dāng) $a =& $b; 時(shí) $a 和 $b 指向了同一個(gè)變量。
提示:$a 和 $b 在這里是完全相同的,這并不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一個(gè)地方。
可以將一個(gè)變量通過引用傳遞給函數(shù),這樣該函數(shù)就可以修改其參數(shù)的值,語法如下:
PHP引用符&
關(guān)于php的引用(就是在變量或者函數(shù)、對(duì)象等前面加上&符號(hào))的作用,我們先看下面這個(gè)程序。代碼如下:
很多人誤解php中的引用跟C當(dāng)中的指針一樣,事實(shí)上并非如此,而且很大差別。C語言中的指針除了在數(shù)組傳遞過程中不用顯式申明外,其他都需要使用*進(jìn)行定義,而php中對(duì)于地址的指向(類似指針)功能不是由用戶自己來實(shí)現(xiàn)的,是由Zend核心實(shí)現(xiàn)的,php中引用采用的是“寫時(shí)拷貝”的原理,就是除非發(fā)生寫操作,指向同一個(gè)地址的變量或者對(duì)象是不會(huì)被拷貝的。
php默認(rèn)為傳值傳遞,代碼如下:
要是想變?yōu)榈刂穫鬟f需要加&,既代碼如下:
就是說,&把$a的地址傳給了$b,這樣的話這兩個(gè)變量現(xiàn)在共享一個(gè)內(nèi)存的存儲(chǔ)區(qū)域,就是說它們的值是一樣的。
同樣的語法可以用在函數(shù)中,它返回引用,以及用在 new 運(yùn)算符中,代碼如下:
引用做的第二件事是用引用傳遞變量,這是通過在函數(shù)內(nèi)建立一個(gè)本地變量,并且該變量在呼叫范圍內(nèi)引用了同一個(gè)內(nèi)容來實(shí)現(xiàn)的,說的通俗點(diǎn)就是一個(gè)函數(shù)的參數(shù)是一個(gè)本地變量的引用,下面再舉例說明一下:
運(yùn)行這段代碼是給函數(shù)傳遞兩個(gè)參數(shù),一個(gè)是引用$a的內(nèi)容,一個(gè)是$b的值,在執(zhí)行此函數(shù)后,發(fā)現(xiàn)$a的內(nèi)容改變了,而$b的內(nèi)容則沒有變化。
PHP引用以及誤區(qū)
PHP中的引用可以理解成變量的別名,由于PHP的變量名是存儲(chǔ)在符號(hào)表(symbol table)中的,變量內(nèi)容是存儲(chǔ)在堆中,引用就是用符號(hào)表中的不同符號(hào)(symbol)名稱來訪問同一存儲(chǔ)內(nèi)容,和Unix文件系統(tǒng)中的hardlink是同一個(gè)概念,比如實(shí)例代碼如下:
傳遞引用
引用傳遞很簡單,就是一個(gè)「&」符號(hào),比如如下代碼:
返回引用
大多數(shù)情況下并不需要返回引用來提高性能,zend引擎會(huì)自己進(jìn)行優(yōu)化,但是如果你非得返回引用得話,可以按照以下方式來返回引用,代碼如下:
與指針的區(qū)別
引用與指針很像,但是其并不是指針,看如下的代碼:
由于$b只是$a的別名,所以即使$b被釋放了,$a沒有任何影響,但是指針可不是這樣的,看如下代碼:
由于b是指向a的指針,所以釋放了b的內(nèi)存之后,再訪問a就會(huì)出現(xiàn)錯(cuò)誤,比較明顯的說明了PHP引用與C指針的區(qū)別。
對(duì)象與引用
在PHP中使用對(duì)象的時(shí)候,大家總是被告知“對(duì)象是按照引用傳遞的”,其實(shí)這是個(gè)誤區(qū),PHP的對(duì)象變量存儲(chǔ)的是此對(duì)象的一個(gè)標(biāo)示符,在傳遞對(duì)象的時(shí)候,其實(shí)傳遞的就是這個(gè)標(biāo)示符,而并不是引用,看如下代碼:
如果對(duì)象是按照引用傳遞的,那么$a, $b, $c輸出的內(nèi)容應(yīng)該一樣,事實(shí)上結(jié)果并非如此,看下面通過引用傳遞對(duì)象的列子:
此時(shí)$aa,$bb,$cc三者內(nèi)容完全一樣,所以可以看出對(duì)象并不是按照引用傳遞,要盡快走出這個(gè)誤區(qū).