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
相关文章
相关标签/搜索