深入理解PHP内核(五)变量及数据类型-变量的结构和类型
原文链接:http://www.orlion.ga/238/
编程语言的类型可以分为强类型和弱类型两种,PHP是弱类型语言,但是C语言是强类型语言。在官网PHP实现内部,所有变量使用同一种数据结构(zval)来保存,这个结构表示PHP中的各种数据类型,它不仅包含变量的值,也包含变量的类型。这就是PHP弱类型的核心。
那zval结构是如何实现弱类型的呢?
一、PHP变量类型及存储结构
PHP在声明和使用变量的时候,并不需要指明其数据类型,PHP是弱类型语言,但是PHP有类型,PHP有八中数据类型,可以分成三类:标量类型:boolean、integer、float(double) string;复合类型:array、object;特殊类型:resource、NULL
C语言是如何实现PHP中的弱类型的呢?
1、变量存储结构
变量的值存储到如下所示的zval结构体中,zval结构体定义在Zend/zend.h文件,其结构如下:
typedef struct _zval_struct zval;
...
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
zval结构体中有四个字段,其含义分别为:
| 属性名 | 含义 | 默认值 |
| refcount_gc | 表示引用计数 | 1 |
| is_ref_gc | 表示是否为引用 | 0 |
| value | 存储变量的值 | |
| type | 变量具体的类型 |
在PHP5.3之后,引入了新的垃圾回收机制,引用计数和引用的字段名改为refcout_gc和is_ref_gc在此之前为refcount和is_ref.
变量的值存储在另外一个结构体zvalue_value,值存储见下面的介绍。
2、变量类型
zval结构体的type字段就是实现弱类型最关键的字段了,type的值可以为:IS_NULL、IS_BOOL、IS_LONG、IS_DOUBLE、IS_STRING、IS_OBJECT和IS_RESOURCE之一。除此之外和它们定义在一起的类型还有IS_CONSTANT、IS_CONSTANT_ARRAY。
二、变量的值存储
前面提到变量的值存储在zvalue_value联合体中,结构体定义如下:
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
各种类型的数据会使用不同的方法来进行变量值的存储,其对应赋值方式如下:
一般类型:
| 变量类型 | 宏 | |
| boolean | ZVAL_BOOL |
布尔型/整型的变量值存储于(zval).value.lval中,其类型也会 以相应的IS_*进行存储 |
| integer | ZVAL_LONG | |
| float | ZVAL_DOUBLE | Z_TYPE_P(z)=IS_BOOL/LONG;Z_LVAL_P(z)=(b)!=0; |
| null | ZVAL_NULL |
NULL值的变量值不需要存储,只需要把(zval).type标为IS_NUL Z_TYPE_P(z)=IS_NULL; |
| resource | ZVAL_RESOURCE |
资源类型的存储与其他一般变量无异,但其初始化及存储实现则不 同Z_TYPE_P(z) = IS_RESOURCE; Z_LVAL_P(z) = 1; |
字符串
字符串的类型标示和其他数据类型一样,不过在存储字符串时多了一个字符串长度的字段。
struct {
char *val;
int len;
} str;
(存储字符串长度是因为字符串的操作十分频繁,有利于节省时间,是空间换时间的做法)
数组Array
数组是PHP中最常用也是最强大变量类型。数组的值存储在zvalue_value.ht字段中,它是一个HashTable类型的数据。PHP数组使用哈希表来存储关联数据。PHP的哈希表实现中使用了两个数据结构HashTable和Bucket。PHP所有的工作都是由哈希表实现。
对象Object
PHP的对象是一种复合型的数据,使用一种zend_object_value的结构体来存放,其定义如下
typedef struct _zend_object_value {
zend_object_handle handle; // unsigned int类型,EG(objects_store).object_buckets的索引
zend_object_handlers *handlers;
} zend_object_value;
PHP的对象只有在运行时才会被创建,前面介绍了EG宏,这是一个全局结构体由于保存在运行时的数据。其中就包括了用来保存所有被创建的对象的对象池,EG(objects_store),而object对象值内容的zend_object_handle域就是当前对象在对象池中所在的索引,handlers字段则是将对象进行操作时的处理函数保存起来。
PHP的弱变量容器的实现方式是兼容并包的形式体现。
深入理解PHP内核(五)变量及数据类型-变量的结构和类型的更多相关文章
- ECMAScript1.1 js书写位置 | 声明变量 | 基本数据类型 | 数据类型转换 | 操作符 | 布尔类型的隐式转换
js书写位置 由于在写css样式时使用的时双引号,所以我们在写js代码时建议使用单引号(‘’)! 行内式 <input type="button" value="点 ...
- 深入理解PHP内核(五)函数的内部结构
php的函数包括用户定义的函数.内部函数(print_r count...).匿名函数.变量函数($func = 'print_r'; $func(array('a','b'));) PHP内核源码中 ...
- Python变量及数据类型
所有编程语言几乎都会有 ’ 变量‘ ,如 a = 2,用一个a变量指代数字2,在Python中,一切皆对象,因此在变量赋值的时候实际上是在内存中开辟了一块存储变量内容的内存空间对象. 对象可以指定不同 ...
- Java学习笔记之——变量与数据类型、运算符
一.变量 1.变量:变化的值 变量在代码运行期间,开辟了一块空间 .这块空间是有地址的,给这块取了个名字, 这个名字就叫做变量名,这块空间放的东西叫做变量值 2.变量的初始化: (1)先声明再赋值: ...
- java 变量及数据类型、原码、反码、补码
Java基础——变量及数据类型 变量的概念 内存中的一个存储区域 变量名+数据类型 可在同一类型范围内不断变化 为什么定义变量: 用于不断的存放同一类型的常量,并可以重复使用 使用变量注意: 变量的作 ...
- Java 数据类型 & 变量与常量 & 注释
一.数据类型 1.数据类型分类 Java 的数据类型分为两大类: 基本数据类型:整数.浮点数.字符型.布尔型 引用数据类型(对象类型):类.数组,字符串.接口等. 2.基本数据类型 四类八种基本数据类 ...
- JAVA数据类型,变量,转换,常量,运算符
java数据类型: Java基本类型共有八种,基本类型可以分为三类: 1.字符类型char,用单引号赋值 2.布尔类型boolean 3.数值类型byte.short.int.long.float.d ...
- C#变量与数据类型
数据类型: 整型:int short long byte 小数:double float decimal 布尔:bool 字符:char 定义变量: 数据类型 变量名 [= 值]; 变量名的命名规则: ...
- Java基础复习之一篇:关健字,标识符,注释,常量,进制转换,变量,数据类型,数据类型转换
1.关健字 1.1.被Java语言赋予特定意义的单词(如:class,interface,public ,static) 1.2.全部是小写 1.3.注意事项(goto和const作为关健字保留起来) ...
随机推荐
- ASDM through site to site VPN
网上大部分文档只提到两个地方需要设置: 在6.2版本确实可以.但在7.2版本上只有用vpn client或anyconnect client连上的客户端可以用ASDM连上ASA,而通过site to ...
- U盘的不识别问题
1.案例: 我重新装过电脑以后出现过一个问题是: 我的U盘只能在我电脑上用,在其他电脑上不能用 其他人的U盘不能在我的电脑上用. 2.根本问题: 是驱动问题.接口上没符合的驱动,未能指定路径.电脑上可 ...
- LNMP 部署
一.防火墙配置 CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙. 1.关闭firewall: systemctl stop firewalld.servic ...
- php学习笔记2016.1
基本类型 PHP是一种弱类型语言. PHP类型检查函数 is_bool() is_integer() is_double() is_string() is_objec ...
- unity 状态机 + svn + 码云 上篇
最近刚找到在实习,忙于公司一个c++ 项目 ,一直想写博客来着,没时间写今天熬夜打算先献上自己前几天自己封装的一个fsm状态机 话不多说,直接上正题,这篇博客主要是在学校的时候状态机一直使用的是pla ...
- MongoDB与内存
来自 http://www.ttlsa.com/mongodb/mongodb-and-memory/# 但凡初次接触MongoDB的人,无不惊讶于它对内存的贪得无厌,至于个中缘由,我先讲讲Linu ...
- Icident event 分析
现象 备库中断,显示如下错误 Connect_Retry: 60 Master_Log_File: mysql-bin.000185 Read_Master_Log_Pos: 308647804 Re ...
- 你以为的ASP.NET文件上传大小限制是你以为的吗
我们以为的文件大小限制 我们大家都知道ASP.NET为我们提供了文件上传服务器控件FileUpload,默认情况下可上传的最大文件为4M,如果要改变可上传文件大小限制,那么我们可以在web.confi ...
- 【Win10】UAP/UWP/通用 开发之 RelativePanel
[Some information relates to pre-released product which may be substantially modified before it's co ...
- 公共代码参考(httpclient)
public class HttpClientUtils { private static final String CHARSET = "UTF-8"; /* * http ge ...