PHP 面试题 目录

PHP 中的变量是如何存储的?

推荐答案

在 PHP 中,变量是通过 zval 结构体来存储的。zval 是 PHP 内部用来表示变量的数据结构,它包含了变量的值、类型、引用计数等信息。PHP 的变量存储机制是基于引用计数和写时复制(Copy-On-Write)的。

本题详细解读

zval 结构体

zval 是 PHP 中用来表示变量的核心数据结构。它的定义如下:

-- -------------------- ---- -------
------ ------------ -
    ---------- ------        -- ----
    ----- -
        ------ -
            -------------------
                ---------- -----         -- ----
                ---------- -----------  -- ----
                ---------- ------------ -- ----
                ---------- ---------    -- ----
        - --
        -------- ----------  -- ----
    - ---
    ----- -
        -------- ----------  -- ----
        -------- -----       -- ----------
        -------- ----------- -- ---
        -------- -------     -- --
        -------- ---------   -- ----
        -------- -------     -- ------- --
        -------- -------------- ------- -----
    - ---
--

变量类型

PHP 中的变量类型是动态的,zval 中的 type 字段用于标识变量的当前类型。常见的类型包括:

  • IS_LONG:整数类型
  • IS_DOUBLE:浮点数类型
  • IS_STRING:字符串类型
  • IS_ARRAY:数组类型
  • IS_OBJECT:对象类型
  • IS_BOOL:布尔类型
  • IS_NULL:NULL 类型

引用计数

PHP 使用引用计数来管理内存。每个 zval 都有一个引用计数(refcount),表示有多少个变量或符号指向这个 zval。当引用计数为 0 时,PHP 会自动释放该 zval 占用的内存。

写时复制(Copy-On-Write)

PHP 使用写时复制机制来优化内存使用。当多个变量指向同一个 zval 时,它们共享同一个 zval。只有当其中一个变量尝试修改 zval 的值时,PHP 才会创建一个新的 zval 副本,并将修改应用到副本上。

变量作用域

PHP 中的变量作用域分为全局作用域和局部作用域。全局变量存储在 $GLOBALS 数组中,而局部变量存储在函数或方法的符号表中。当函数执行结束时,局部变量的 zval 引用计数会减少,如果引用计数为 0,则内存会被释放。

变量销毁

当变量超出作用域或显式调用 unset() 函数时,PHP 会减少 zval 的引用计数。如果引用计数为 0,PHP 会释放该 zval 占用的内存。

示例

在这个示例中,$a$b 最初共享同一个 zval,但当 $b 被修改时,PHP 会创建一个新的 zval 副本。

纠错
反馈