溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

php中傳值與傳引用有什么不同

發(fā)布時(shí)間:2020-11-02 11:01:40 來源:億速云 閱讀:172 作者:小新 欄目:編程語言

小編給大家分享一下php中傳值與傳引用有什么不同,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

傳值是將變量的值復(fù)制出一份新的值;在函數(shù)范圍內(nèi),改變變量值得大小,不會(huì)影響到函數(shù)外邊的變量值。傳引用是將變量的引用復(fù)制出來一份;在函數(shù)范圍內(nèi),對值的任何改變,在函數(shù)外部也有所體現(xiàn),因?yàn)閭饕脗鞯氖莾?nèi)存地址。

php傳值:在函數(shù)范圍內(nèi),改變變量值得大小,都不不會(huì)影響到函數(shù)外邊的變量值。

PHP按引用:在函數(shù)范圍內(nèi),對值的任何改變,在函數(shù)外部也有所體現(xiàn),因?yàn)閭饕脗鞯氖莾?nèi)存地址。

傳值和傳引用、傳地址的區(qū)別:

1、傳值,是把實(shí)參的值賦值給行參

那么對行參的修改,不會(huì)影響實(shí)參的值

2、傳地址

是傳值的一種特殊方式,只是他傳遞的是地址,不是普通的如int

那么傳地址以后,實(shí)參和行參都指向同一個(gè)對象

3、傳引用

真正的以地址的方式傳遞參數(shù)

傳遞以后,行參和實(shí)參都是同一個(gè)對象,只是他們名字不同而已

對行參的修改將影響實(shí)參的值

大牛的解釋:

傳值:和copy是一樣的?!敬騻€(gè)比方,我有一橦房子,我給你建筑材料,你建了一個(gè)根我的房子一模一樣的房子,你在你的房子做什么事都不會(huì)影響到我,我在我的房子里做什么事也不會(huì)影響到你,彼此獨(dú)立?!?/p>

<?php 
$testa=1; //定義變量a 
$testb=2; //定義變量b 
$testb = $testa; //變量a賦值給變量b 
echo $testb; //顯示為1 
?>

傳引用:類似于C語言的指針了,感覺差不多。打個(gè)比方,我有一橦房子,我給你一把鑰匙,我們二個(gè)都可以進(jìn)入這個(gè)房子,你在房子做什么都會(huì)影響到我。

【優(yōu)缺點(diǎn):】傳值會(huì)很耗時(shí)間,特別是對于大型的字符串和對象來說,這將會(huì)是一個(gè)代價(jià)很大的操作,傳送引用,函數(shù)內(nèi)的任何操作等同于對傳送變量的操作,傳送大型變量時(shí)效率高!

1.先來解釋一下名詞。

值傳遞(passl-by-value)過程中,被調(diào)函數(shù)的形式參數(shù)作為被調(diào)函數(shù)的局部變量處理,即在堆棧中開辟了內(nèi)存空間以存放由主調(diào)函數(shù)放進(jìn)來的實(shí)參的值,從而成為了實(shí)參的一個(gè)副本。值傳遞的特點(diǎn)是被調(diào)函數(shù)對形式參數(shù)的任何操作都是作為局部變量進(jìn)行,不會(huì)影響主調(diào)函數(shù)的實(shí)參變量的值。

引用傳遞(pass-by-reference)過程中,被調(diào)函數(shù)的形式參數(shù)雖然也作為局部變量在堆棧中開辟了內(nèi)存空間,但是這時(shí)存放的是由主調(diào)函數(shù)放進(jìn)來的實(shí)參變量的地址。被調(diào)函數(shù)對形參的任何操作都被處理成間接尋址,即通過堆棧中存放的地址訪問主調(diào)函數(shù)中的實(shí)參變量。正因?yàn)槿绱?,被調(diào)函數(shù)對形參做的任何操作都影響了主調(diào)函數(shù)中的。

注意:上面紅字部分說明,應(yīng)用傳遞不是不開辟空間,是開辟空間的,只不過開辟的空間是用來存放實(shí)參變量地址的。

2.php中引用的用法有以下三種。

①. 變量的引用賦值: $a = &$b

②. 函數(shù)調(diào)用時(shí)的引用參數(shù)傳遞

1) 早期php是在調(diào)用時(shí)通過&符號傳遞引用類型的變量, 比如: func(&$arg);

2) 后來, 函數(shù)的引用類型參數(shù)被規(guī)定為需要在函數(shù)聲明時(shí)定義, 不如: function func(&$arg);

注意:引用聲明時(shí)定義引用類型參數(shù)后,運(yùn)行時(shí)引用參數(shù)傳遞被廢棄,需要在php.ini中增加allow_call_time_pass_reference來開啟.

③. 函數(shù)返回引用類型,這種應(yīng)用方式需要聲明函數(shù)時(shí),在函數(shù)名前增加&符號,并且,在調(diào)用時(shí),要用引用賦值方式, 實(shí)例代碼如下:

function &func() {
    return $a;
}
$a = func();  //這種調(diào)用方式得到的不是引用傳值
$a =& func(); //這樣調(diào)用才是引用傳值
$a = 1;
function &func(&$a) {
  return $a;
}
$b = func($a);
$c =& func($a);
$b = 2;
echo "a: $a, b: $b, c: $c. <br />/n";
//輸出a: 1, b: 2, c: 1.
//可見對$b的修改不會(huì)影響$a
$c = 3;
echo "a: $a, b: $b, c: $c. <br />/n";
//輸出a: 3, b: 2, c: 3.
//可見對$c的修改會(huì)影響$a

請看下面詳細(xì)的例子:

3.php各種數(shù)據(jù)類型傳值/指針

一、基本數(shù)據(jù)類型的傳值

/* **************************************************** */ 
function testvar($k){
 $k = 40;
}
$c = 30;
//給一個(gè)函數(shù)參數(shù)傳一個(gè)基本數(shù)據(jù)類型(整型,布爾,字符 ...), 實(shí)際上傳的就是值 ;
testvar($c);
echo $c;//結(jié)果是:30
function testvar2(&$k){
 $k = 40;
}
$e = 30;
//給一個(gè)函數(shù)參數(shù)傳一個(gè)基本數(shù)據(jù)類型(整型,布爾,字符 ...), 實(shí)際上傳的y就是地址 ;
testvar2($e);
echo $e;//結(jié)果是:40
  
/* **************************************************** */

二、數(shù)組(默認(rèn)情況下是復(fù)制一份數(shù)據(jù)),如要傳地址則&$arr

 1 $arr1 = array(-1,5,0); 
 2 function testArr($arr){ 
 3  for($i=0;$i<count ($arr);$i++){ 
 4   for($j=$i+1;$j<count($arr);$j++){ 
 5    if($arr[$i]>$arr[$j]){ 
 6     $temp = $arr[$i]; 
 7     $arr[$i] = $arr[$j]; 
 8     $arr[$j] = $temp; 
 9    } 
10   } 
11  
12  } 
13  print_r($arr);  //結(jié)果:Array ( [0] => -1 [1] => 0 [2] => 5 )  
14 } 
15 testArr($arr1); 
16 print_r($arr1);  //結(jié)果:Array ( [0] => -1 [1] => 5 [2] => 0 )  
17  
18 function testArr2(&$arr){ 
19  for($i=0;$i</count><count ($arr);$i++){ 
20   for($j=$i+1;$j<count($arr);$j++){ 
21    if($arr[$i]>$arr[$j]){ 
22     $temp = $arr[$i]; 
23     $arr[$i] = $arr[$j]; 
24     $arr[$j] = $temp; 
25    } 
26   } 
27  
28  } 
29 } 
30 testArr($arr1); 
31 print_r($arr1);  //結(jié)果:Array ( [0] => -1 [1] => 0 [2] => 5 )

三、對象數(shù)據(jù)類型傳值

class person{
 public $name;
 public  $age;
}
  
$a = new person();
$a->name = '小明';
$a->age = '20';
//變量a在存的是對象的地址,把a(bǔ)賦給b這個(gè)變量,實(shí)際上就是賦了一個(gè)地址。
$b = $a;
$b->age = 30;
//echo $a->age.$b->age;//結(jié)果是:30 30
//給一個(gè)函數(shù)參數(shù)傳一個(gè)對象, 實(shí)際上傳的是這個(gè)對象的地址;
function test($k){
 $k->age =40;
}
//調(diào)用
test($b);
//echo $a->age.$b->age;//結(jié)果是:40 40

在PHP5中 對象的復(fù)制 是通過引用來實(shí)現(xiàn)的。上列中$a=new person; $b=$a; 其實(shí)等效于$a=new person; $b=&$a;
PHP5中默認(rèn)就是通過引用來調(diào)用對象, 但有時(shí)你可能想建立一個(gè)對象的副本,并希望原來的對象的改變不影響到副本 . 為了這樣的目的,PHP定義了一個(gè)特殊的方法,稱為__clone.

4.php寫時(shí)拷貝

php中對于地址的指向(類似指針)功能不是由用戶自己來實(shí)現(xiàn)的,是由Zend核心實(shí)現(xiàn)的,php中引用采用的是“寫時(shí)拷貝”的原理,就是除非發(fā)生寫操作,指向同一個(gè)地址的變量或者對象是不會(huì)被拷貝的。

通俗的講

1:如果有下面的代碼

$a="ABC";
 $b=$a;

其實(shí)此時(shí)$a與$b都是指向同一內(nèi)存地址而并不是$a與$b占用不同的內(nèi)存

2:如果在上面的代碼基礎(chǔ)上再加上如下代碼

$a="EFG";

由于$a與$b所指向的內(nèi)存的數(shù)據(jù)要重新寫一次了,此時(shí)Zend核心會(huì)自動(dòng)判斷自動(dòng)為$b生產(chǎn)一個(gè)$a的數(shù)據(jù)拷貝,重新申請一塊內(nèi)存進(jìn)行存儲(chǔ)。

5.php引用于C指針的區(qū)別

在PHP 中引用的意思是:不同的名字訪問同一個(gè)變量內(nèi)容.
與C語言中的指針是有差別的.C語言中的指針里面存儲(chǔ)的是變量的內(nèi)容在內(nèi)存中存放的地址。

PHP 的引用允許你用兩個(gè)變量來指向同一個(gè)內(nèi)容

$a="ABC";
$b =&$a;
echo $a;//這里輸出:ABC
echo $b;//這里輸出:ABC
$b="EFG";
echo $a;//這里$a的值變?yōu)镋FG 所以輸出EFG
echo $b;//這里輸出EFG

當(dāng)你 unset 一個(gè)引用,只是斷開了變量名和變量內(nèi)容之間的綁定。這并不意味著變量內(nèi)容被銷毀了。例如:

unset($a);
echo $b;//這里輸出EFG

以上是php中傳值與傳引用有什么不同的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI