PHP-引用变量

2019-03-06  本文已影响0人  AGEGG

1.&引用变量

//定义变量a,为变量a在内存中开辟一块空间
$a = range(0,1000);
var_dump(memory_get_usage());
//COW Copy On Write 机制 $b指向了$a的内存空间,共享空间
$b = $a;
var_dump(memory_get_usage());

//对$a进行修改 此时,$b还是指向$a创建出来的空间,$a修改了,因此copy出$a指向新开辟的空间
$a = range(0,1000);
var_dump(memory_get_usage());
$a = range(0,1000);
var_dump(memory_get_usage());
//$b指向$a的内存空间
$b = &$a;
var_dump(memory_get_usage());
//这时再对$a做修改,$a必然与$b值相同,因为指向了同一块内存空间
$a = range(0,1000);
var_dump(memory_get_usage());

2.zval变量容器

$a = range(0,3);
//需要安装xdebug拓展
xdebug_debug_zval('a');
/**
*输出为:
*a:(refcount=1,is_ref=0)=array()
*/
//refcount=1 1个变量在指向这个空间
//is_ref=0 是不是引用,0:false
$a = range(0, 3);
xdebug_debug_zval('a');
//定义变量b,把a的值赋值给b
$b = $a;
xdebug_debug_zval('a');
/**
*输出为:
*a:(refcount=1,is_ref=0)=array()
*a:(refcount=2,is_ref=0)=array()refcount=2因为$a与$b都指向这个空间
*/
$a = range(0, 3);
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
//修改a
$a = range(0, 3)
xdebug_debug_zval('a');
/**
*输出为:
*a:(refcount=1,is_ref=0)=array()
*a:(refcount=2,is_ref=0)=array()
*a:(refcount=1,is_ref=0)=array()refcount=1因为$a进行了写操作,不再指向该空间,复制了一份指向新空间
*/
$a = range(0, 3);
xdebug_debug_zval('a');
$b = &$a;
xdebug_debug_zval('a');
$a = range(0, 3)
xdebug_debug_zval('a');
/**
*输出为:
*a:(refcount=1,is_ref=0)=array()$a指向该空间
*a:(refcount=2,is_ref=1)=array()$a,$b指向该空间,引用变为true
*a:(refcount=2,is_ref=1)=array()$a,$b指向该空间,引用变为true
*/

3.注意点

//unset只会取消引用,不会销毁空间
$a = 1;
$b = &$a;
unset($b);
echo $a;//1 只取消掉$b的引用,未销毁空间,$a还是指向该空间
//对象本身就是引用传递
class Person
{
  public $name = "zhangsan";
}
$p1 = new Person;
xdebug_debug_zval('p1');
$p2 = $p1;
xdebug_debug_zval('p1');
$p2->name = "lisi";
xdebug_debug_zval('p1');
*输出为:
*p1:(refcount=1,is_ref=0)=class Person{public $name=(refcount=2,is_ref=0)='zhangsan'}
*p1:(refcount=2,is_ref=0)=class Person{public $name=(refcount=2,is_ref=0)='zhangsan'}
*p1:(refcount=2,is_ref=0)=class Person{public $name=(refcount=1,is_ref=0)='lisi'}//对象不会对空间进行复制
*/

EX

ex1:
<?php
$data = ['a','b','c'];
foreach ($data as $key => $val) {
  $val = &data[$key];
}
问:每次循环$data值与执行结束$data值?
1.
$k = 0
$v = a//新空间a
$v = $d[0]//新空间$d[0],同时$v也指向这块空间
2.
$k = 1
$v = b//空间$d[0]值从a变为b
$v = $d[1]//新空间$d[1],同时$v也指向这块空间
3.
$k = 2
$v = c
d[1] = c//空间d[1]值从b变为c
$v = $d[2]//新空间$d[2],同时$v也指向这块空间

[a,b,c]
[b,b,c]
[b,c,c]
ex2:
<?php
$arr = [['price'=>10, 'count' => 100],['price' =>20, 'count' => 90]];
foreach ($arr as &$val) {
    $val['total']=$val['price']*$val['count'];
}
print_r($arr);
/**
* 
*Array
*(
*    [0] => Array
*        (
*            [price] => 10
*            [count] => 100
*            [total] => 1000
*        )
*
*    [1] => Array
*        (
*            [price] => 20
*            [count] => 90
*            [total] => 1800
*        )
*
*)
*
*/
//等效于:
foreach($arr as $k => $val) {
  $arr[$k]['total'] = $val['price']*$val['count'];
}
上一篇下一篇

猜你喜欢

热点阅读