变量在 PHP7 内部的实现(二)

以下是“变量在 PHP7 内部的实现(二)”的完整攻略。

什么是变量

变量是一个可存储数据的容器,在 PHP 中我们必须先声明变量然后再给其赋值。变量名称由一个美元符号 "$" 开始,后面跟着变量的名称。

在 PHP7 中,变量的实现是通过结构体 zval 实现的。zval(Zend Value)是 PHP 变量的内部表示,所有的 PHP 值都必须使用 zval 才能在 PHP 中表示和操作。

zval 结构体

下面是 zval 结构体定义:

typedef struct _zval_struct zval;

struct _zval_struct {
    /* variable value */
    union {
        long         lval;    /* long 整型 */
        double       dval;    /* 双精度浮点型 */
        zend_refcounted *counted;
        zend_string     *str; /* 字符串 */
        zend_array      *arr; /* 数组 */
        zend_object     *obj; /* 对象 */
        zend_resource   *res; /* 资源 */
        zend_reference  *ref; /* 引用 */
        void          *ptr;
        zend_ast       *ast;
    } value;

    /* variable information */
    unsigned    int    type:3;       /* 值的类型 */
    unsigned    int    count:30;     /* 引用计数 */
    union {
        uint32_t    flags;            /* 引用计数相关的标记 */
        uint32_t    next;             /* hash chained bucket */
        uint32_t    cache_slot;       /* cache slot (for RECV_INIT) */
        uint32_t    opline_num;       /* opcode number (for _RECV_VR) */
        uint32_t    num_args;         /* arguments number for EX(This) */
        uint32_t    fe_pos;           /* foreach position */
        uint32_t    fe_iter_idx;      /* foreach iterator index */
    } u1;

    union {
        uint32_t    var_flags;        /* flags for $... */
        uint32_t    next;             /* hash chained bucket */
        uint32_t    cache_slot;       /* cache slot (for RECV_INIT) */
        uint32_t    label;            /* label position */
        uint32_t    opline_num;       /* opline number (for _DECLARE_ANON_CLASS) */
        uint32_t    num_args;         /* arguments number for EX(This) */
        uint32_t    fe_iter_idx;      /* foreach iterator index */
    } u2;
};

可以看到 zval 实际上是一个联合体,它可以代表 long, double, string, array, object, resource, reference 等多种类型。

zval 的引用计数

在 PHP 中,引用计数用于判断一个 zval 是否已经被垃圾回收,如果一个 zval 的引用计数为0,那么 PHP 核心将会回收它。因此,当我们使用一个已经被释放的 zval 时,可能会发生堆栈故障(segmentation fault)等问题。

zval 结构体中的 count 字段就是用来维护引用计数的,它的值就是指向该值的变量的数量即:可通过单一的变量声明n次来引用同一值。例如:

$a = 123;
$b = $a;
$c = &$b;

在上述 PHP 代码中,$a, $b, $c 分别是三个 zval,它们的值都是 123。同时,$b 和 $c 都是 $a 的别名(即引用)。此时,三个 zval 的引用计数都是 1。

示例说明

下面通过两个示例,来说明 PHP7 中 zval 的使用:

示例一:变量的类型转换

$x = 123;  // $x 是一个整型变量
$x = 123.0;  // $x 变成了一个浮点型变量

当我们给 zval 赋值时,PHP7 会根据变量的值来选择合适的 zval 类型。当变量的值发生改变时,PHP7 会检查该变量的类型,然后尝试将其转换为新的类型。在上述代码中,当 $x 赋值为 123 时,PHP7 会创建一个整型的 zval,当 $x 的值变为 123.0 时,在存储 $xzval 中的 type 字段被改为了浮点型类型。

示例二:foreach 循环中的引用计数自增

$arr = [1, 2, 3];
foreach ($arr as &$data) {}

在上述代码中,我们使用 foreach 循环遍历数组 $arr。由于 $data 是一个引用,因此 PHP7 内部会将 $data 的引用计数加 1。由于 $data$arr 中的一个元素,因此 PHP7 也会将该元素的引用计数加 1。这种引用计数的自增策略,能够避免在循环结束后,$data 的引用计数被错误地减 1,同时也能够避免因为在循环中修改元素值过程中,无法实时的同步更新数组元素值的问题。

在上面的两个示例中,我们可以看到 PHP7 内部是如何使用 zval 来实现变量存储和操作的,并且通过对 zval 的引用计数的维护,能够使 PHP7 能够更加高效地管理内存。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:变量在 PHP7 内部的实现(二) - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • php中chdir()函数用法实例

    PHP中chdir()函数用法实例 简介 chdir()函数属于PHP函数库中的一种文件操作函数,由于其可以改变当前工作目录,所以也被称为变更当前工作目录函数。在Linux和Unix操作系统中,chdir()函数常用于修改当前系统的工作目录,而在Windows系统下,更多的是在Web应用程序中,通过改变工作目录来操作和管理文件。 函数说明 函数原型为: bo…

    PHP 2023年5月27日
    00
  • PHP读取网页文件内容的实现代码(fopen,curl等)

    如果要在 PHP 中读取网页文件的内容,可以使用 fopen() 函数或 curl 库。下面将分别讲解它们的实现代码及其使用方法。 使用 fopen() 函数读取网页文件 fopen() 函数可以实现打开一个 URL (如一个网页文件),并返回该文件的句柄。我们可以使用 fgets() 函数读取文件中的一行或 file_get_contents() 函数读取…

    PHP 2023年5月23日
    00
  • javascript里使用php代码实例

    前言 在使用 JavaScript 构建应用程序时,通常需要从服务器获取数据。可以使用各种编程语言编写服务器端逻辑,如 PHP、Python、Node.js 等。其中,PHP 是最常见的选择之一。在 JavaScript 中使用 PHP 代码可以让我们更方便、高效地处理数据。 本篇攻略将引导您如何在 JavaScript 中使用 PHP 代码,包括从服务器获…

    PHP 2023年5月24日
    00
  • php中intval()的实例用法

    下面是“PHP中intval()的实例用法”的完整攻略,包含代码示例和详细讲解。 什么是intval()? intval()是PHP中的一个函数,用于将变量转换为整数类型。其完整的定义为: int intval ( mixed $var [, int $base = 10 ] ) 其中,$var为要转换为整数的变量,$base为可选参数,表示要将 $var …

    PHP 2023年5月26日
    00
  • php实现改变图片直接打开为下载的方法

    要实现将图片直接下载而不是显示的功能,可以通过以下步骤来实现: 创建一个下载链接,网站需要提供一个下载链接给用户,用户点击之后即可下载图片。下载链接需要指向一个用于下载图片的php文件。 在php文件中添加下面的代码,将图片转换为可下载的文件并将其发送给用户: “`php

    PHP 2023年5月27日
    00
  • php实现签到功能的方法实例分析

    下面我来为您详细讲解“php实现签到功能的方法实例分析”的完整攻略。 一、准备工作 在开始实现签到功能之前,我们需要进行一些准备工作,如:1. 安装好PHP开发环境。2. 确定数据库类型,如Mysql等,并连接好数据库。3. 创建好签到表,记录用户签到信息。 二、实现签到功能 创建签到页面,包括对应的HTML表单。 编写PHP代码实现签到功能: 判断用户是否…

    PHP 2023年5月27日
    00
  • 学习php设计模式 php实现状态模式

    下面是“学习php设计模式 php实现状态模式”的完整攻略。 什么是状态模式 状态模式,也称状态机模式(State Pattern或者State Machine Pattern),是一种行为型设计模式。它允许对象在其内部状态发生变化时改变它的行为,而不是在代码里面用一堆的 if else 来控制。 状态模式可以让代码更清晰、更简洁,并且更容易扩展和维护。它给…

    PHP 2023年5月27日
    00
  • 微信怎么删除下拉小程序?微信下拉小程序删除关闭教程

    下面是详细讲解删除微信下拉小程序的攻略: 1. 了解微信下拉小程序 微信下拉小程序是指,在微信中下拉屏幕可以展示部分小程序内容的功能。如果你打开了一个小程序,并且正在使用时下拉屏幕,则可以在微信首页的小程序栏目中看到顶部出现该小程序的内容。如果你不希望看到该小程序的下拉内容,可以选择删除该小程序的下拉功能。 2. 删除微信下拉小程序 方法一:长按小程序图标 …

    PHP 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部