PHP - 基础 - 引用变量

PHP的引用变量的概念及定义方式

概念

在PHP中引用意味着用不同的名字访问同一个变量内容.

定义方式

使用 & 符号

PHP引用变量的原理

工作原理

  • 定义变量

    • Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php

    // 1.定义一个变量 (内存地址1)
    $a = range(0, 1000);

    // 2.定义变量b, 将a变量的值赋值给b (内存地址1)
    // COW: Copy On Write
    $b = $a;

    // -------------------
    // $a, $b 指向同一内存空间
    // -------------------
    ?>
    • 图示

  • 修改变量

    • Code

      1
      2
      3
      4
      5
      6
      7
      8
      9
          <?php
      // 3.修改变量, (内存地址2)
      $a = range(0, 1000);

      // -------------------
      // $a -> (内存地址2)
      // $b -> (内存地址1)
      // -------------------
      ?>
    • 图示


  • 引用变量

    • Code

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <?php
      // 1.定义一个变量 (内存地址1)
      $a = range(0, 1000);
      // 2.引用变量, $b指向$a的内存地址
      $b = &$a;

      // -------------------
      // $a -> (内存地址2)
      // $b -> (内存地址2)
      // -------------------
      ?>
    • 图示

  • 引用变量

    • Code

      1
      2
      3
      4
      5
      6
      7
      8
      9
       <?php
      // 4.修改变量, (内存地址2的内容被修改)
      $a = range(0, 1000);

      // -------------------
      // $a -> (内存地址2)
      // $b -> (内存地址2)
      // -------------------
      ?>
    • 图示

unset

unset 只会取消引用, 不会销毁空间

  • unset

    • Code

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
       <?php
      // 定义变量, ($a内存地址1)
      $a = 1;
      // 引用变量, ($b内存地址1)
      $b = &$a;
      // 取消引用
      unset($b);

      // -------------------
      // $a -> (内存地址1)
      // $b -> NULL
      // -------------------
      ?>
    • 图示

对象

修改对象属性时, 只会对修改的属性进行赋值, 不会将整个对象复制.

问题

写出如下程序的输出结果

1
2
3
4
5
6
<?php
$data = ['a', 'b', 'c'];
foreach($data as $key => $val)
{
$val = &$data[$key];
}

  1. 程序运行时, 每一次循环结束后变量$data的值是什么?
  2. 程序执行完成后, 变量$data的值是什么?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 程序共3次循环
// 第一次:
$key = 0; $val = 'a';
$val = &$data[0] = 'a';
// 此时 $data = ['a', 'b', 'c']

// 第二次:
$key = 1;
$val = 'b';
// $data[0] 与 $val 指向同一内存, 所以 $data[0] = 'b';
$val = &$data[1] = 'b';
// 此时 $data = ['b', 'b', 'c']

// 第三次:
$key = 2;
$val = 'c';
// $data[1] 与 $val 指向同一内存, 所以 $data[1] = 'c';
$val = &$data[2] = 'c';
// 此时 $data = ['b', 'c', 'c']

// 执行完成后: $data = ['b', 'c', 'c']

使用 memory_get_usage()获取当前使用的内存量

COW(Copy on Write)写入时复制:
一种计算机程序设计领域的优化策略。其核心思想是,如果有多个调用者(callers)同时要求相同资源(如内存或磁盘上的数据存储),他们会共同获取相同的指针指向相同的资源,直到某个调用者试图修改资源的内容时,系统才会真正复制一份专用副本(private copy)给该调用者,而其他调用者所见到的最初的资源仍然保持不变。这过程对其他的调用者都是透明的(transparently)。此作法主要的优点是如果调用者没有修改该资源,就不会有副本(private copy)被创建,因此多个调用者只是读取操作时可以共享同一份资源。