1. 文章
  2. 文章详情

PHP中值传递(传值)和引用传递(传引用)解析

值传递:值传递是将原变量内容复制下来,再用一个新的内存空间来保存,两个变量之间相互独立。在函数范围内,改变变量值得大小,都不会影响到函数外边的变量值。

引用传递:相当于给当前变量起了一个别名,实际上这两个变量引用的是一个值。相当于给一个变量起了两个名字。在函数范围内,对值的任何改变,在函数外部也有所体现,因为传引用传的是内存地址。

对于较大的数据,传引用比较好,可以节省内存的开销。

PHP中值传递(传值)和引用传递(传引用)解析

按值传递

函数范围内对值的任何改变在函数外部都会被忽略,值传递是把值拷贝一份,两个变量指向两个内存地址

$a = 6;
$b = $a; // 这是值传递,把 $a 的值拷贝给了 $b,在内存中 $a 和 $b 不在一个地址中,更改任意变量的值对对方无影响
$b = 7;
echo $a; // 输出:6
function foo($b){
 echo ++$b;
}
foo($b); // 输出:8   
echo $b; // 输出:7    说明函数内的改变对函数外的值没有影响,因为,当 $b 传入函数内的时候是值传递,会把值在内存中拷贝一份存入一个新的内存地址中 

按引用传递

函数范围内对值的任何改变在函数外部也能反映出这些修改

引用传递是将一个变量的内存地址标识传给了内外一个变量,两个变量最终指向内存同一个地址

重点是引用传递

以及引用传递易犯错误说明,如下:

$a = 6;

$b = &$a;

$b = 7;

echo $a; // 输出:7 

function foo(&$c){

echo ++$c;

}

foo($b); // 输出:8   

echo $b; // 输出:8    说明函数内的改变对函数外的值有影响,因为,当 $b 传入函数内的时候是引用传递,函数体内的$b和外部的$b实际上是指向同一个内存地址,所以一个改变,另外一个变量的值也会改变

引用传值进阶示例:

function func(&$arr){

$arr['a'] = [];

$arr = &$arr['a'];

$arr['b'] = '333';

var_dump($arr);

}

$arr = [

    'a' => '111',

    'b' => '222'

];

func($arr);

var_dump($arr);

/**

# 第一个输出:

array(1) {

  ["b"]=> string(3) "333"

}

# 第二个输出:

array(2) {

  ["a"]=> array(1) {

      ["b"]=> string(3) "333"

  }

  ["b"]=> string(3) "222"

}

*/

上面的示例明明还是引用传递进去的为啥会两个 $arr 打印出不一样的结果呢?

因为里面有一步操作 $arr = &$arr['a']; 这一步之后函数内的 $arr 的指向地址已经改变,指向了$arr['a'],所以两次打印的结果不一样

php 中对于对象默认引用传值

一般引用传值用在需要在函数体内改变传入参数并且需要影响外部变量的时候使用,其他时候一般使用值传递

PHP写时拷贝

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

通俗的讲

1: 如果有下面的代码

 $a="ABC";

 $b=$a;

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

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

$a="EFG";

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

php 引用于 C 指针的区别

在 PHP 中引用的意思是:不同的名字访问同一个变量内容.

与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址。

PHP 的引用允许你用两个变量来指向同一个内容(引用传值相当于给变量起了个别名)

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

更多文章:

  1. 指针和内存
  2. 一 维数组和二维数组内存示意图
  3. 十个 PHP 开发者最容易犯的错误
  4. php 函数值传值 / 地址以及引用的用法

参考:https://blog.csdn.net/u010324331/article/details/88911948

发表评论

登录后才能评论

评论列表(0条)