首頁 >後端開發 >PHP問題 >php中傳值與傳引用的差異有哪些?

php中傳值與傳引用的差異有哪些?

青灯夜游
青灯夜游原創
2020-10-30 17:12:224189瀏覽

傳值是複製變數的值一個新的值;在函數範圍內,改變變數值得大小,不會影響到函數外邊​​的變數值。傳引用是將變數的引用複製出來一份;在函數範圍內,對值的任何改變,在函數外部也有所體現,因為傳引用傳的是記憶體位址。

php中傳值與傳引用的差異有哪些?

推薦:《PHP影片教學

php傳值:在函數範圍內,改變變數值得大小,都不不會影響到函數外邊​​的變數值。

PHP按引用:在函數範圍內,對值的任何改變,在函數外部也有所體現,因為傳引用傳的是記憶體位址。

傳值與傳引用、傳送位址的區別:

1、傳值,是把實參的值賦值給行參

那麼對行參的修改,不會影響實參的值

2、傳遞位址

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

那麼傳送位址以後,實參和行參都指向同一個物件

3、傳引用

真正的以位址的方式傳遞參數

傳遞以後,行參和實參都是同一個對象,只是他們名字不同而已

對行參的修改將影響實參的值

大牛的解釋:

傳值:和copy是一樣的。 【打個比方,我有一橦房子,我給你建築材料,你建了一個根我的房子一模一樣的房子,你在你的房子做什麼事都不會影響到我,我在我的房子裡做什麼事也不會影響到你,彼此獨立。 】

<?php 
$testa=1; //定义变量a 
$testb=2; //定义变量b 
$testb = $testa; //变量a赋值给变量b 
echo $testb; //显示为1 
?>

傳引用:類似C語言的指標了,感覺差不多。打個比方,我有一橦房子,我給你一把鑰匙,我們二個都可以進入這個房子,你在房子裡做什麼都會影響我。

【優缺點:】傳值會很耗時間,特別是對於大型的字串和物件來說,這將會是一個代價很大的操作,傳送引用,函數內的任何操作等同於傳送變數的操作,傳送大型變數時效率高!

1.先來解釋名詞。

值傳遞(passl-by-value)過程中,被調函數的形式參數作為被調函數的局部變數處理,即在堆疊中開闢了記憶體空間以存放由主調函數放進來的實參的值,從而成為了實參的一個副本。值傳遞的特徵是被調函數對形式參數的任何操作都是作為局部變數進行,不會影響主調函數的實參變數的值。

引用傳遞(pass-by-reference)過程中,被調函數的形式參數雖然也作為局部變數在堆疊中開闢了記憶體空間,但是這時存放的是由主調函數放進來的實參變數的位址。被調函數對形參的任何操作都被處理成間接定址,即透過堆疊中存放的位址存取主調函數中的實參變數。正因為如此,被調函數對形參做的任何操作都影響了主調函數中的。

注意:上面紅字部分說明,應用傳遞不是不開闢空間,是開闢空間的,只不過開闢的空間是用來存放實參變數位址的。

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

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

②.函數呼叫時的引用參數傳遞

   1) 早期php是在呼叫時透過&符號傳遞引用類型的變數, 例如: func(&$arg);

   2) 後來, 函數的引用型別參數被規定為需要在函數宣告時定義, 不如: function func(&$arg);

注意:引用聲明時定義引用類型參數後,運行時引用參數傳遞被廢棄,需要在php.ini中增加allow_call_time_pass_reference來開啟.

#③.函數回傳參考型別,這個應用方式需要宣告函數時,在函數名稱前增加&符號,並且,在呼叫時,要用引用賦值方式, 實例程式碼如下:

function &func() {
    return $a;
}
$a = func();  //这种调用方式得到的不是引用传值
$a =& func(); //这样调用才是引用传值
$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的修改不会影响$a
$c = 3;
echo "a: $a, b: $b, c: $c. <br />/n";
//输出a: 3, b: 2, c: 3.
//可见对$c的修改会影响$a

請看下面詳細的例子:

3.php各種資料型別傳值/指標

一、基本資料型別的傳值

/* **************************************************** */ 
function testvar($k){
 $k = 40;
}
$c = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的就是值 ;
testvar($c);
echo $c;//结果是:30
function testvar2(&$k){
 $k = 40;
}
$e = 30;
//给一个函数参数传一个基本数据类型(整型,布尔,字符 ...), 实际上传的y就是地址 ;
testvar2($e);
echo $e;//结果是:40
  
/* **************************************************** */

二、陣列(預設情況下是複製一份資料),如要傳送位址則&$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);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )  
14 } 
15 testArr($arr1); 
16 print_r($arr1);  //结果: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);  //结果:Array ( [0] => -1 [1] => 0 [2] => 5 )

三、物件資料型別傳值

class person{
 public $name;
 public  $age;
}
  
$a = new person();
$a->name = &#39;小明&#39;;
$a->age = &#39;20&#39;;
//变量a在存的是对象的地址,把a赋给b这个变量,实际上就是赋了一个地址。
$b = $a;
$b->age = 30;
//echo $a->age.$b->age;//结果是:30 30
//给一个函数参数传一个对象, 实际上传的是这个对象的地址;
function test($k){
 $k->age =40;
}
//调用
test($b);
//echo $a->age.$b->age;//结果是:40 40

在PHP5中物件的複製是透過引用來實現的。上列中$a=new person; $b=$a; 其實等效於$a=new person; $b=&$a;
PHP5中預設就是透過引用來呼叫對象, 但有時你可能想建立一個物件的副本,並希望原來的物件的改變不影響到副本. 為了這樣的目的,PHP定義了一個特殊的方法,稱為__clone.

4.php寫時拷貝

php中对于地址的指向(类似指针)功能不是由用户自己来实现的,是由Zend核心实现的,php中引用采用的是“写时拷贝”的原理,就是除非发生写操作,指向同一个地址的变量或者对象是不会被拷贝的。

通俗的讲

1:如果有下面的代码

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

其实此时$a与$b都是指向同一内存地址而并不是$a与$b占用不同的内存

2:如果在上面的代码基础上再加上如下代码

$a="EFG";

由于$a与$b所指向的内存的数据要重新写一次了,此时Zend核心会自动判断自动为$b生产一个$a的数据拷贝,重新申请一块内存进行存储。

5.php引用于C指针的区别

在PHP 中引用的意思是:不同的名字访问同一个变量内容.
与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址。

PHP 的引用允许你用两个变量来指向同一个内容

$a="ABC";
$b =&$a;
echo $a;//这里输出:ABC
echo $b;//这里输出:ABC
$b="EFG";
echo $a;//这里$a的值变为EFG 所以输出EFG
echo $b;//这里输出EFG

当你 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁了。例如:

unset($a);
echo $b;//这里输出EFG

相关推荐:php培训

以上是php中傳值與傳引用的差異有哪些?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn