引用变量 --- 2021-11-13

2021-11-13  本文已影响0人  一位先生_

概念:
在PHP中引用变量意味着,使用不同的变量名去访问同一个变量的内容。

定义方式:使用 & 符号

demo1.php

<?php 

//定义一个变量
$a = range(1,9999);
var_dump(memory_get_usage());//获取为变量开辟空间变化

//定义变量b 将变量a的值赋值给变量b
//cow 机制 copy on write
$b = $a;

var_dump(memory_get_usage());

//对变量a进行修改
$a = range(1,9999);

var_dump(memory_get_usage());


 ?>

总结:变量a发生了改变,因cow机制,会进行开辟内存空间,内存空间发生变化。
demo2.php

<?php 

//定义一个变量
$a = range(1,9999);
var_dump(memory_get_usage());

//定义变量b 将变量a的值赋值给变量b
//cow 机制 copy on write
$b = &$a;

var_dump(memory_get_usage());

//对变量a进行修改
$a = range(1,9999);

var_dump(memory_get_usage());


 ?>

总结:demo2和demo1相比较,变量b 引用了变量a的地址空间,即使变量a发生了改变,空间也不会发生改变。

demo3.php(这个需要自己安装xdebug扩展)

<?php 

    //zval 变量容器
    $a = range(0, 5);
    xdebug_debug_zval('a');

    //将变量a的值赋值给b
    $b = $a;
    xdebug_debug_zval('a');

    $a = range(0, 5);
    xdebug_debug_zval('a');
 ?>

运行结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=2, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)

总结:将变量a赋值给变量b refcount值加1,此时为2,但是并没有引用;当变量a的值发生改变时,refcount从1开始,此时也没有引用 is_ref为0 即false。

demo4.php

<?php 

    //zval 变量容器
    $a = range(0, 5);
    xdebug_debug_zval('a');

    //将变量a的值赋值给b
    $b = &$a;
    xdebug_debug_zval('a');

    $a = range(0, 5);
    xdebug_debug_zval('a');
 ?>

结果:
a: (refcount=1, is_ref=0)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)

a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)

a: (refcount=2, is_ref=1)=array (0 => (refcount=0, is_ref=0)=0, 1 => (refcount=0, is_ref=0)=1, 2 => (refcount=0, is_ref=0)=2, 3 => (refcount=0, is_ref=0)=3, 4 => (refcount=0, is_ref=0)=4, 5 => (refcount=0, is_ref=0)=5)

总结:demo4相比较于demo3使用了引用,即变量b引用了变量a; 在引用之后refcount还是2,并不会开辟新的空间;
is_ref = 1; 说明使用了引用变量。

demo5.php

<?php 

    //unset只会取消引用,并不会销毁空间
    $a = 1;

    $b = &$a;

    unset($b);
    var_dump($a);
    // echo $b; //b 此时已经进行了销毁

 ?>

总结:unset只会取消引用,但并不会销毁空间地址,因为此时打印出变量a的值是1。

demo6.php

<?php 

//对象本身就是引用传值
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=0, is_ref=0)='zhangsan' } p1: (refcount=2, is_ref=0)=class Person { publicname = (refcount=0, is_ref=0)='zhangsan' }
p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=0, is_ref=0)='lisi' }

总结:对象本身就是引用传值

example.php

<?php 
    $data = [a,b,c];

    foreach ($data as $key => $value) {
        $value = &$data[$key];
        var_dump($data);
    }
    var_dump($data);

 ?>

结果:
/home/example.php:6:
array(3) {
[0] =>
string(1) "a"
[1] =>
string(1) "b"
[2] =>
string(1) "c"
}
/home/example.php:6:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "b"
[2] =>
string(1) "c"
}
/home/example.php:6:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "c"
[2] =>
string(1) "c"
}
/home/example.php:8:
array(3) {
[0] =>
string(1) "b"
[1] =>
string(1) "c"
[2] =>
string(1) "c"
}

image.png
上一篇下一篇

猜你喜欢

热点阅读