• 题(2)


    1、请写出下列的结果:

    $a = 123;
    $b = &$a;
    
    var_dump($b);//123
    
    $a = 456;
    var_dump($b);//456
    
    
    unset($a);
    var_dump($b);//456

    关于变量引用:

      (1)普通的变量赋值。

        执行COW机制,即copy On Write。

        当一个变量等于另一个变量时,并没有增加一块新空间的开销,而是两个变量指向同一个内存空间;  

        当其中一个变量重写时(无论值是否改变),会为这个重写的变量增加一块单独的内存空间。 

        示例:

    $a = range(0,1000);
    var_dump(memory_get_usage());//打印内存,878408
    
    $b = $a;
    var_dump(memory_get_usage());//打印内存,878408,发现没变化或变化很小
    
    $a = range(0,1000);//$a重新赋值,虽然值没有变化
    var_dump(memory_get_usage());//打印内存,915328,发现变化很大,因为$a重新使用了一块空间。

      (2)当进行引用赋值。

        变量永远指向同一个内存空间,所以内存不会变化或变化很小。

    $a = range(0,1000);
    var_dump(memory_get_usage());//打印内存,878408
    
    $b = &$a;
    var_dump(memory_get_usage());//打印内存,878432,发现变化很小
    
    $a = range(0,1000);//$a重新赋值,虽然值没有变化
    var_dump(memory_get_usage());//打印内存,878432,发现没变化或变化很小。

      扩展:可以打印zval结构体来查看变量的底层的存储,zval就是变量容器,管理变量内容。安装xdebug扩展。

    $a = range(1,3);
    $b = &$a; xdebug_debug_zval(
    'a');

      recount=1;说明只有一个变量指向这个内存空间。

      is_ref=1;说明有一个引用


    2、关于对象的赋值:

    class user{
        public $name = '';
    
        public function setName($newName = ''){
            $this->name = $newName;
        }
    
        public function getName(){
            return $this->name;
        }
    }
    
    $a = new user();
    $b = $a;
    $c = clone $a;
    $a->setName('123');
    var_dump($b->getName());//string '123'
    var_dump($c->getName());//string ''

    正确结果是:123;说明对象之间的赋值,本身就是引用传值,指向同一个内存空间,如果不想使用同一个对象,就需要使用clone关键字复制一个对象。


    3、请分析下面程序,写出结果:

    $data = array('a','b','c');
    foreach ($data as $k => $v) {
        $v = &$data[$k];
    }
    问:
    (1)程序运行时,每一次循环结束后变量$data的值是什么,请解释。
    (2)程序执行完成后,变量$data的值是什么?请解释。
    
    分析:
    第一轮循环:
        $k=0;
        $v='a';
        $v = &$data[0];//$v和$data[0]指向同一个空间
    
        所以第一轮结果:
        $data = array('a','b','c');
    
    第二轮循环:
        $k=1;
        $v='b';//因为第一轮$v和$data[0]指向同一个空间,所以$v变化,$data[0]就变化。
        $v = &$data[1];//$v和$data[1]又指向同一个空间
    
        所以第二轮结果:
        $data = array('b','b','c');    
    
    
    第三轮循环:
        $k=2;
        $v='c';//因为第二轮$v和$data[1]指向同一个空间,所以$v变化,$data[1]就变化。
        $v = &$data[2];//$v和$data[2]又指向同一个空间
    
        所以第二轮结果:
        $data = array('b','c','c');    
    
    最终结果:
    var_dump($data);//array('b','c','c');

  • 相关阅读:
    restful风格
    拦截器(拦截都是控制层的地址。 filter: )
    Springmvc完成ajax功能,controller类返回的数据类型为String且为汉字时出现乱码
    文件上传
    Springmvc完成ajax功能。(jquery. $)
    Controller如何进行重定向跳转
    Maven学习日志一
    SSM整合
    Spring学习日志四
    Spring学习日志三
  • 原文地址:https://www.cnblogs.com/gyfluck/p/13918174.html
走看看 - 开发者的网上家园