php 引用变量知识点

一、什么是引用变量?在php中,用什么符号定义引用变量?
引用变量:用不同的名字访问同一个变量内容

定义方式:使用&符号


二、引用变量衍生知识点

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']
 */



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值