传值和传引用的理解
-
请问PHP中传值与传引用的区别?
- 传值: 在函数范围内,改变变量的值不好影响到函数外边的变量值。
- 传引用: 在函数范围内, 对变量值的任何改变,函数外部的变量会跟随改变,因为传引用传的是内存地址。
-
什么时候传值,什么时候传引用?
- 需要在函数内部的改变变量值的时候可以传引用, 如
array_pop
,array_push
函数。 - 对于较大的变量传引用较好,可以节省内存开销,因为传值调用需要复制变量。
- 需要在函数内部的改变变量值的时候可以传引用, 如
-
php7与php5引用的实现原理?
-
在php5使用的是引用计数, 使用refcount_gc来记录次数,is_ref_gc来记录是否为引用类型。
-
$a = 'hello world!'
,$a
进行赋值操作,此时refcount_gc=1
。 -
$b = $a
, 此时$a
和$b
指向的是同一个结构体,并且refcount_gc=2
。 -
$c = &$b
, 此时传址方式将$b
赋值给$c
, 此时就需要进行分离了,$a
还是指向之前的结构体,$b
和$c
指向新的结构体,$a
还是指向原来的结构体,此时$b
和$c
指向的结构体is_ref_gc=1
, 但是值和$a
中还是相等,但是需要维护两个值为hello wolrd!
的zval,浪费内存。
-
-
在php7中引入了_zend_reference结构体, 引用成为一种变量类型, 其指向了一个zval结构体。
struct _zend_reference { zend_refcounted_h gc; zval val; };
当使用
&
操作变量时,会创建一个新的中间结构体_zend_reference
, 这个结构体会指向真正的zend_string
结构体,但是zend_string
结构体的引用计数并不会发生变化,同时zend_reference
结构体的引用计数为2,$b
和$c
均变为zend_reference
, 好处在于zend_string
始终只有一份, 节省内存开销
-