美文网首页
PHP引用变量相关问题

PHP引用变量相关问题

作者: 陈智涛 | 来源:发表于2017-10-23 23:32 被阅读0次

    什么是引用变量?

    在PHP中引用意味着用不同的名字访问同一个变量内容
    定义方式:
    使用&符号

    1、普通变量赋值依据cow机制,

    1.1 vim demo1.php
    <?
    //定义一个变量
    $a = range(0,1000);
    var_dump(memory_get_usage());
    //定义一个变量b,将a变量赋值给b
    //根据cow copy on wirte 机制,如果a没有被重新进行写操作,b不会开辟新的内存空间
    $b = $a;
    var_dump(memory_get_usage());//对比第一次,内存不会有明显变化
    //对a进行修改
    $a = range(0,1000);
    var_dump(memory_get_usage());//由于对a重新赋值,b也被赋予新的内存空间
    ?>
    

    运行结果:

    [root@chen php]# php demo1.php
    int(366104)
    int(366240)
    int(510744)
    

    1.2 x_debug_zval显示变量的引用情况

    <?php
    $a = range(0,10);
    xdebug_debug_zval('a');
    $b = $a;
    xdebug_debug_zval('a');
    $a = range(0,10);
    xdebug_debug_zval('a');
    

    运行结果:

    a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    a: (refcount=2, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    
    屏幕快照 2017-10-24 上午10.32.32.png

    2、使用引用赋值

    2.1 vim demo2.php
    <?
    //定义一个变量
    $a = range(0,10);
    var_dump(memory_get_usage());
    //定义一个变量b,将a变量赋值给b
    //根据cow copy on wirte 机制,如果a没有被重新进行写操作,b不会开辟新的内存空间
    $b = &$a;
    var_dump(memory_get_usage());
    //对a进行修改
    $a = range(0,10);
    
    var_dump(memory_get_usage());
    ?>
    
    

    运行结果:

    [root@chen php]# php demo2.php
    int(223352)
    int(223488)
    int(223464)
    

    结果显示,使用引用后,b就指向a的内存地址,a被重新写入,b的值也不会变化。

    2.2 x_debug_zval显示变量的引用情况
    <?php
    $a = range(0,10);
    xdebug_debug_zval('a');
    $b = &$a;
    xdebug_debug_zval('a');
    $a = range(0,10);
    xdebug_debug_zval('a');
    

    运行结果:

    a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    a: (refcount=2, is_ref=1)=array (0 => (refcount=1, is_ref=0)=0, 1 => (refcount=1, is_ref=0)=1, 2 => (refcount=1, is_ref=0)=2, 3 => (refcount=1, is_ref=0)=3, 4 => (refcount=1, is_ref=0)=4, 5 => (refcount=1, is_ref=0)=5, 6 => (refcount=1, is_ref=0)=6, 7 => (refcount=1, is_ref=0)=7, 8 => (refcount=1, is_ref=0)=8, 9 => (refcount=1, is_ref=0)=9, 10 => (refcount=1, is_ref=0)=10)
    
    屏幕快照 2017-10-24 上午10.45.09.png

    3、引用的销毁 unset

    注意:unset只会取消引用,不会销毁空间
    示例:
    vim demo5.php

    <?php
    <?php
    $a = 1;
    $b = &$a;
    unset($b);
    echo $a."\n";
    

    运行结果:

    [root@chen php]# php demo5.php
    1
    

    对象本省就是引用传值,不需要引用符号

    示例1:

    <?php
    class Person{
        public $name = 'chenzhitao';
    }
    $p1 = new Person;
    xdebug_debug_zval('p1');
    $p2 = $p1;
    xdebug_debug_zval('p1');
    $p2->name = 'Jason';
    xdebug_debug_zval('p1');
    

    运行结果:

    [root@chen php]# php demo6.php
    p1: (refcount=1, is_ref=0)=class Person { public $name = (refcount=2, is_ref=0)='chenzhitao' }
    p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=2, is_ref=0)='chenzhitao' }
    p1: (refcount=2, is_ref=0)=class Person { public $name = (refcount=1, is_ref=0)='Jason' }
    
    屏幕快照 2017-10-24 上午10.59.57.png

    示例2:

    <?php
    
    /**
     * 写出如下程序的输出结果
     * <?php
     *
     * $data = ['a', 'b', 'c'];
     *
     * foreach($data as $key => $val)
     * {
     *      $val = &$data[$key];
     * }
     * 程序运行时,每一次循环结束后变量$data的值是什么?请解释
     * 程序执行完成后,变量$data的值是什么?请解释
     */
    
    $data = ['a', 'b', 'c'];
    
    foreach ($data as $key=>$val)
    {
        $val = &$data[$key];
        var_dump($data);
    }
    
    var_dump($data);
    

    运行结果:

      [0]=>
      &string(1) "a"
      [1]=>
      string(1) "b"
      [2]=>
      string(1) "c"
    }
    array(3) {
      [0]=>
      string(1) "b"
      [1]=>
      &string(1) "b"
      [2]=>
      string(1) "c"
    }
    array(3) {
      [0]=>
      string(1) "b"
      [1]=>
      string(1) "c"
      [2]=>
      &string(1) "c"
    }
    array(3) {
      [0]=>
      string(1) "b"
      [1]=>
      string(1) "c"
      [2]=>
      &string(1) "c"
    }
    
    

    相关文章

      网友评论

          本文标题:PHP引用变量相关问题

          本文链接:https://www.haomeiwen.com/subject/ewqzuxtx.html