php中按值传递和按引用传递的一个问题

  php中传递变量默认是按照值传递。php

  简单举个例子:数组

 1 <?php
 2 
 3 function testArray($arr){// &$arr
 4     $arr = array(1,2,3,);
 5 }
 6 
 7 $array = array(4, 5);
 8 
 9 testArray($array);
10 
11 print_r($array);// Array ( [0] => 4 [1] => 5 )

若是testArray的参数写成$arr,那么数组$array的结果不会变。证实是按照值传递。函数

若是参数强制改为引用传递,函数参数要写成&$arr,结果才是Array ( [0] => 1 [1] => 2 [2] => 3 )this

 

再举一个对象的例子:spa

 1 <?php
 2 
 3 class Person{
 4     public $age = 0;
 5     function __construct($age)
 6     {
 7         $this->age = $age;
 8     }
 9 }
10 
11 function testObj1($p){
12     $p->age = 2;
13 }
14 
15 function testObj2($p){
16     $p = null;
17 }
18 
19 function testObj3(&$p){
20     $p = null;
21 }
22 
23 $p1 = new Person(1);
24 
25 echo $p1->age,'<br/>';// 1
26 
27 testObj1($p1);
28 echo $p1->age,'<br/>';// 2
29 
30 testObj2($p1);
31 echo $p1->age,'<br/>';// 2
32 
33 testObj3($p1);
34 echo $p1->age,'<br/>';// null

对象也依然是按照值传递。这个值是栈区的地址。code

有人会说,为何按照值传递,28行还会是2。对象

若是用个堆栈模型演示一下就很明白了,$p1这个变量是存在栈区,它存放了一块地址,这块地址指向了堆区里的对象。blog

此时调用了testObj1()函数,那么会在函数栈里面,再生成一个$p变量,它也存放了一块地址,这个地址和$p1存放的地址相同,表示$p也指向堆区的那个位置。因此说改变$p堆的对象属性,$p1也跟着变。io

当调用testObj2()函数时,它让函数栈区的$p指向了空,可是它并无改变$p1的指向,$p1仍然指向的那块堆地址。因此仍然是2。function

当调用testObj3()函数时,函数取的是$p1的地址(注意区别,$p1自己在栈里是有个地址的,它存放的数据也是个地址,这两个地址是不同的),直接操纵了$p1,表示让$p1指向空。所以$p1也就没有了属性值。

相关文章
相关标签/搜索