一、什么是引用变量?在php中,用什么符号定义引用变量?
引用变量:用不同的名字访问同一个变量内容
2、针对上面程序改为引用变量后,效果又不一样
3、查看写时复制时php内核zval结构体数据
4、查看写时改变时php内核zval结构体数据
5、unset:只会取消引用,不会销毁空间
6、对象本身就是引用传递
三、利用内存变量变动画图解决引用变量题目
引用变量:用不同的名字访问同一个变量内容
定义方式:使用&符号
二、引用变量衍生知识点
1、写时复制(Copy On Write)
<?php
/**
* 演示写时复制(Copy On Write)
*/
var_dump(memory_get_usage());//357896
// 定义一个变量
$a = range(0, 1000);
var_dump(memory_get_usage());//386616
// 定义变量b,将a变量的值赋值给b,此时a和b公用一个空间
// COW Copy On Write
$b = $a;
var_dump(memory_get_usage());//386616
// 对a进行修改,此时对b拷贝一份,再对a重新开辟数据空间
$a = range(0, 1000);
var_dump(memory_get_usage());//415336
2、针对上面程序改为引用变量后,效果又不一样
<?php
/**
* 引用变量,a和b都是公用一块空间
*/
var_dump(memory_get_usage());//357720
// 定义一个变量
$a = range(0, 1000);
var_dump(memory_get_usage());//386440
// 定义变量b,将a变量的值赋值给b
$b = &$a;
var_dump(memory_get_usage());//386464
// 对a进行修改,由于a和b公用一块空间,所以此步骤不会导致a和b都各自占用各自空间
$a = range(0, 1000);
var_dump(memory_get_usage());//386464
3、查看写时复制时php内核zval结构体数据
<?php
/**
* 查看写时复制时php内核zval结构体数据
* refcount: 指向这个zval变量容器的变量个数
* is_ref:是否被引用
*/
// zval变量容器
$a = range(0, 3);
xdebug_debug_zval('a');//refcount=1, is_ref=0)
// 定义变量b,把a的值赋值给b
$b = $a;
xdebug_debug_zval('a');//refcount=2, is_ref=0)
// 修改a
$a = range(0, 3);//此处进行写时拷贝,refcount减1
xdebug_debug_zval('a');//refcount=1, is_ref=0
xdebug_debug_zval('b');//refcount=1, is_ref=0
4、查看写时改变时php内核zval结构体数据
<?php
/**
* 查看写时改变时php内核zval结构体数据
* refcount: 指向这个zval变量容器的变量个数
* is_ref:是否被引用
*/
$a = range(0, 3);
xdebug_debug_zval('a');//refcount=1, is_ref=0
$b = &$a;
xdebug_debug_zval('a');//refcount=2, is_ref=1
$a = range(0, 3);
xdebug_debug_zval('a');//refcount=2, is_ref=1
$c = $a;//写时改变
xdebug_debug_zval('a');//refcount=2, is_ref=1
xdebug_debug_zval('b');//refcount=2, is_ref=1
xdebug_debug_zval('c');//refcount=2, is_ref=0
5、unset:只会取消引用,不会销毁空间
<?php
/**
* unset 只会取消引用,不会销毁空间
*/
$a = 1;
$b = &$a;
unset($b);
echo $b. "\n";//Notice: Undefined variable
echo $a. "\n";//1
6、对象本身就是引用传递
<?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');
var_dump($p1->name);//lisi
var_dump($p2->name);//lisi
三、利用内存变量变动画图解决引用变量题目
<?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);//['b','c','c']
/*
* 最终结果为['b','c','c']
* 分析
* 第一次循环:
* key = 0;
* val = 'a';//val赋值为'a'
* val = &$data[0];//val指向data[0]
*
* 第二次循环
* key = 1;
* val = 'b',//此处由于val引用data[0],那么val='b',也相当于data[0] = 'b'
* val = &$data[1];val指向data[1]
*
* 第三次循环
* key = 2;
* val = 'c',//此处由于val引用data[1],那么val='c',也相当于data[1] = 'c'
* val = &$data[2];val指向data[2]
*
* 最终数组data的数据为['b','c','c']
*/