PHP变量底层原理

news2024/11/23 22:19:52

前言

        PHP是解释型的语言,它的执行顺序主要会经过以下几步:

        1. 进行词法分析

        2. 进行语法分析

        3. 通过zend编译器,编译成opcode

        4. zend虚拟机执行opcode

        我们在写PHP代码的时候就知道,PHP是弱语言类型,而PHP底层又是由zend虚拟机来执行的,zend虚拟机又是C语言编写的,C语言又是强类型的语言,那么PHP是怎么做到弱语言变成强语言类型的虚拟机可执行的呢?这里就要先了解到变量的zval结构了。

变量的结构

1. synbol_table符号表

synbol_table全局符号表,使用hashtable数据结构用于存放变量名以及值地址。

当我们定义一个变量 $a =1 ,a是这个变量名,1是变量的值,synbol_table就是存放变量名a和对应1所在的地址。

2. zval结构体

变量值采用的就是zval结构体来实现的,查看PHP源码可以看到zval结构体如下:

struct _zval_struct {
    /* Variable information */
    zvalue_value value; /* value */
    zend_uint refcount_gc;
    zend_uchar type; /* active type */
    zend_uchar is_ref_gc;
};

value: 变量值,它是一个zvalue_value联合,下面会具体介绍它的结构。

refcount_gc: 引用次数,用于变量赋值和垃圾回收使用。

type: 活动的类型,体现这个变量操作时的真实类型,它的值主要有这8种: IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE IS_STRING、IS_ARRAY、IS_OBJECT、IS_RESOURCE

is_ref_gc: 是否引用变量

3. zvalue_value联合

zvalue_value联合列出了PHP语言所支持的所有变量类型,结构如下:

typedef union _zvalue_value {
    long lval;
    double dval;
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;

对于变量定义如下图:   

当我们定义了一个变量 $a =3时,全局hashtable表中存下了变量a和3值得地址,变量值则为struct_zval_struct结构体,value值为 long类型3,type是IS_LONG类型,refcount_gc为1只有变量a在引用,is_ref_gc为0 非引用类型。

变量赋值

1. 变量传值赋值

举例:$a = 10 ; $b = $a;

我们定义了一个变量a=1,接着我们将变量a赋值给变量b。

当我们进行传值赋值时,其实php底层并不会复制,因此这时所占用的内存只有一个,从上面例子中,当我们定义变量a时则会生成一个变量a的zval结构体,这个结构体中refcount_gc=1,is_ref_gc =0,当进行赋值$b = $a时,则原来变量a的结构体中refcount_gc+1 = 2,因为非引用赋值is_ref_gc=0;

2. COW(写时复制)

COW(写时复制)特性,当变量进行写操作时则会复制新的结构体。 

上面例子中$b=$a;而接下去当我们要进行 $b=20 对变量b进行修改成20时,那么会复制一份$b的结构体,此时a的结构体中 refcount_gc-1 =1 ,b的结构体refcount_gc =1。

3. 变量引用赋值

举例:$a = 10 ; $b = &$a;

同样的定义了一个变量a=10;同时变量b赋值的是变量a的地址,这时a和b都是公用同一个结构体,这个结构体中 refcount_gc=2,is_ref_gc =1。无论对a还是对b进行修改,都是修改同一个结构体。

4. 传值和引用赋值混合操作

举例:

$a=10
$b=$a 
$c=&$a
$c=20

第一步:$a=10时, 结构体中 value=10 ,refcount_gc=1 ,is_ref_gc=0;
第二步:$a赋值$b时,结构体为同一个 refcount_gc =2;
第三步:$a引用赋值给$c时,结构体为同一个 refcount_gc=3, is_ref_gc=1;
第四步:$c进行修改时,则分裂一个$b的结构体 ref_count_gc=1 is_ref_gc=0,原结构体ref_count_gc=2 is_ref_gc=1;

总结

        PHP虽然是解释型语言,但是实际上还是需要通过zend虚拟机进行编译成物理机所能执行的语言,所以解释型语言也是需要编译的。同时对于PHP弱语言来讲,其只是对编程人员表现出是弱语言,PHP底层依然还是强类型语言,它是通过zval来实现变量的定义和表现的。

        在变量的zval结构中有一个refcount_gc的字段,这个字段也是PHP垃圾回收机制中很重要的一个标识。当我们使用unset函数时,则会将变量的refcount_gc=0,同时也会将synbol_table表中的变量也删除,这时PHP就会认定这个变量之前的结构体为垃圾数据而进行清理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1050232.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亚马逊无线充UL62368报告办理 无线充UL2738+UL2056标准UL认证办理亚马逊类目审核

什么是UL测试报告和UL认证有什么区别? 美国是一个对安全要求非常严格的国家,美国本土的所有电子产品生产企业早在很多年前就要求有相关安规检测。而随着亚马逊在全球商业的战略地位不断提高,境外的电子设备通过亚马逊不断涌入美国市场&#…

幂级数和幂级数的和函数有什么关系?

幂级数和幂级数的和函数有什么关系? 本文例子引用自:80_1幂级数运算,逐项积分、求导【小元老师】高等数学,考研数学 求幂级数 ∑ n 1 ∞ 1 n x n \sum\limits_{n1}^{\infty}\frac{1}{n}x^n n1∑∞​n1​xn 的和函数 &#xff…

What are the differences between lsof and netstat on linux?

参考:https://stackoverflow.com/questions/49381124/what-are-the-differences-between-lsof-and-netstat-on-linux https://www.cnblogs.com/pc-boke/articles/10012112.html LSOF: List of Open Files. It lists all the open files belonging to all active pr…

C语言实现——简易通讯录

前言:小伙伴们又见面啦!这几天通过我们对自定义数据类型的学习,我们已经掌握了如何同时对多种数据类型进行管理,那么今天这篇文章,我们就来干一件大事——实现简易的通讯录。 一.思路分析 先来想想通讯录有哪些功能&a…

Spring Boot:利用JPA进行数据库的查删

目录标题 DAO 、Service 、 Controller 层控制器文件示例代码-单个查找查找成功示例代码-列表查找查找成功示例代码-删除删除成功 DAO 、Service 、 Controller 层 DAO 层负责数据库访问,它封装了对数据库的访问操作,例如查询、插入、更新和删除等。 Q…

《向量数据库指南》——向量数据库Elasticsearch -> Milvus 2.x

Elasticsearch -> Milvus 2.x 1. 准备 ES 数据 要迁移 ES 数据,前提假设您已经拥有属于自己的 es Server(自建、ElasticCloud、阿里云 ES 等),向量数据存储在 dense_vector,以及其他字段在 index 中,index mapping 形式如: 2. 编译打包 首先下载迁移项目源码:https…

第P7周—咖啡豆识别(1)

数据集及wen件目录介绍: 数据集:工作台 - Heywhale.com 一、前期工作 1.1 数据详情 import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision from torchvision import transforms, datasets import os,…

Ros2 学习02- ubuntu22.04 安装ros2

设置镜像源 sudo vim /etc/apt/sources.list#阿里源 deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ jamm…

小波变换学习笔记【1】

【声明】本博客为学习B站视频小波分解与重构所做笔记,供自己和大家查阅学习,想查看 up 原视频请移步 B 站,侵删。 1.1 小波变换的由来 傅里叶变换基本思想:将信号分解成一系列不同频率的连续正弦波的叠加。 其缺点是,…

数据结构 | 二叉树

基本形状 可参照 数据结构:树(Tree)【详解】_数据结构 树_UniqueUnit的博客-CSDN博客 二叉树的性质 三种顺序遍历

基于Java的演唱会网上订票系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

记录一次SQL注入src挖掘过程

记录一次SQL注入src挖掘过程,小白挖洞 先是使用谷歌语法找到一个可以注入的网站 谷歌语法: 公司inurl:php?id 然后该公司的URL为 URL:XXXXXXXXXX/xxx.php?id1 输入测试有无注入,有没有waf 发现有报错 使用sqlmap寻找注入点 python…

golang 结合 cobra 使用 chatgpt qdrant 实现 ai知识库 cli

golang 结合 cobra 使用 chatgpt qdrant 实现 ai知识库 cli 流程 将数据集 通过 openai embedding 得到向量组装payload,存入 qdrant用户进行问题搜索,通过 openai embedding 得到向量,从 qdrant 中搜索相似度大于0.8的数据从 qdrant 中取出数据得到参考答案将问题标题参考答案…

Flutter笔记:用于ORM的Floor框架简记

Flutter笔记 用于ORM的Floor框架简记 本文地址:https://blog.csdn.net/qq_28550263/article/details/133377191 【介绍】:最近想找用于Dart和Flutter的ORM框架,偶然间发现了Floor,觉得还不错,做一些记录。 1. Floor 框…

likeadmin和fastapi的bug

以下内容写于2023年8月11日 bug 1 请求体 - 多个参数 - FastAPI (tiangolo.com)中“请求体中的单一值”处,选python3.6,接口示例代码是 from typing import Unionfrom fastapi import Body, FastAPI from pydantic import BaseModel from typing_exte…

26662-2011 磁粉制动器 阅读笔记

声明 本文是学习GB-T 26662-2011 磁粉制动器. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了磁粉制动器(以下简称制动器)的术语,技术要求,试验方法,检验规则,标志、包装、运 输和…

【项目实战】单数据源多数据库实现多租户

文章目录 前言多租户的四种实现方案单数据源多数据库实现思路代码实现 总结 前言 多租户(Multi-Tenancy)是一种软件架构设计模式,旨在使单个应用程序可以同时为多个租户(如不同组织、用户或客户)提供服务,…

Python 小爬虫入门 -- 爬取专栏文章标题保存到 CSV 文件中

爬取专栏文章标题保存到 CSV 文件中目标分析网页代码及理解代码段一代码段二成果展示爬取专栏文章标题保存到 CSV 文件中 目标 从一个网页上抓取数据,并保存到一个 CSV 文件中。 具体是爬取 微机系统与接口上机实验_TD PITE型 专栏里的所有 文章标题 并 保存到 csv 文件 中…

估计、偏差和方差

一、介绍 统计领域为我们提供了很多工具来实现机器学习目标,不仅可以解决训练集上的任务,还可以泛化。基本的概念,例如参数估计、偏差和方差,对于正式地刻画泛化、欠拟合和过拟合都非常有帮助。 二、参数估计 参数估计 是统计学…

35 LRU缓存

LRU缓存 题解1 双map(差2个testcases)题解2 哈希表双向链表(参考)题解3 STL:listunordered_map 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正…