PHP傳值、傳引用

PHP傳值和傳引用、傳地址的區別是什麼?php

傳值:數組

是把實參的值賦值給形參,那麼對形參的修改,不會影響實參的值函數


傳地址:this

是傳值的一種特殊方式,只是他傳遞的是地址,不是普通的如int
那麼傳地址之後,實參和形參都指向同一個對象

傳引用:指針

真正的以地址的方式傳遞參數
傳遞之後,形參和實參都是同一個對象,只是他們名字不一樣而已
對形參的修改將影響實參的值

code


 

從函數調用的角度理解比較好

傳值:
函數參數壓棧的是參數的副本,任何的修改是在副本上做用,沒有做用在原來的變量上。對象


傳指針:
壓棧的是指針變量的副本。
當你對指針解指針操做時,其值是指向原來的那個變量,因此對原來變量操做。內存

傳引用:
壓棧的是引用的副本。因爲引用是指向某個變量的,對引用的操做其實就是對他指向的變量的操做。(做用和傳指針同樣,只是不用解引用)  

io

 


 

函數參數傳遞機制的基本理論function


函數參數傳遞機制問題在本質上是調用函數(過程)和被調用函數(過程)在調用發生時進行通訊的方法問題;函數的目的終歸是對目標數據的處理(常見的有,設置變量的值等其它屬性)。

基本的參數傳遞機制有兩種:值傳遞和引用傳遞。

如下討論稱調用其餘函數的函數爲主調函數,被調用的函數爲被調函數:
     

值傳遞(pass-by-value)過程當中,被調函數的形式參數做爲被調函數的局部變量處理,即在堆棧中開闢了內存空間以存放由主調函數放進來的實參的值,從而成爲了實參的一個副本。值傳遞的特色是被調函數對形式參數的任何操做都是做爲局部變量進行,不會影響主調函數的實參變量的值。
     

引用傳遞(pass-by-reference)過程當中,被調函數的形式參數雖然也做爲局部變量在堆棧中開闢了內存空間,可是這時存放的是由主調函數放進來的實參變量的地址。被調函數對形參的任何操做都被處理成間接尋址,即經過堆棧中存放的地址訪問主調函數中的實參變量。正由於如此,被調函數對形參作的任何操做都影響了主調函數中的實參變量。

 如上所述,值傳遞和引用傳遞對實參變量的處理過程是不同的,函數對值的操做和對引用的操做的機制是不同;形參老是被做爲局部變量來處理的,函數會根據在其內存空間中存儲的是實參的值的副本仍是實參的地址的副本分別處理,至於函數是如何區分值和地址的,我不得而知,貌似也沒必要知道。


 


僅討論一下值傳遞和引用:

所謂值傳遞,就是說僅將對象的值傳遞給目標對象,就至關於copy;系統將爲目標對象從新開闢一個徹底相同的內存空間。
所謂引用,就是說將對象在內存中的地址傳遞給目標對象,就至關於使目標對象和原始對象對應同一個內存存儲空間。此時,若是對目標對象進行修改,內存中的數據也會改變。

引用的做用 
若是程序比較大,引用同一個對象的變量比較多,而且但願用完該對象後手工清除它,我的建議用 "&" 方式,而後用$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 永遠是調用它的對象的引用。

補充:
php中對於地址的指向(相似指針)功能不是由用戶本身來實現的,是由Zend核心實現的,php中引用採用的是「寫時拷貝」的原理,就是除非發生寫操做,指向同一個地址的變量或者對象是不會被拷貝的。

 

傳值的話,若是是非對象,會傳一個值的拷貝,對這個變量作任何改動都不影響原值。
傳引用或者傳對象,是傳真實的內存地址,對這個變量作的改動會影響原值。

function func1($a) {
  $a = $a + 1;
}
function func2(&$a) {
  $a = $a + 1;
}
$sample = 1;
func1($sample); 
echo $sample; // 輸出 1

$sample = 1;
func2($sample); 
echo $sample; // 輸出 2
相關文章
相關標籤/搜索