0

0

【PHP内核学习】变量和数据类型

php中文网

php中文网

发布时间:2016-06-23 13:57:36

|

1335人浏览过

|

来源于php中文网

原创

          <p class="sycode">              |=-----------------------------------------------------------------------=|          </p>          <p class="sycode">              |=---------------------=[ PHP内核中的变量和数据类型]=--------------------=|          </p>          <p class="sycode">              |=-----------------------------------------------------------------------=|          </p>          <p class="sycode">              |=--------------------------=[ by d4shman ]=-----------------------------=|          </p>          <p class="sycode">              |=-----------------------------------------------------------------------=|          </p>          <p class="sycode">              |=-------------------------=[  May 6, 2014  ]=---------------------------=|          </p>          <p class="sycode">              |=-----------------------------------------------------------------------=|          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              (_____ \| |   | (_____ \   /\   / _____) |  / )             </p>          <p class="sycode">               _____) ) |__ | |_____) ) /  \ | /     | | / /              </p>          <p class="sycode">              |  ____/|  __)| (_____ ( / /\ \| |     | |< <               </p>          <p class="sycode">              | |     | |   | |     | | |__| | \_____| | \ \              </p>          <p class="sycode">              |_|     |_|   |_|     |_|______|\______)_|  \_)   (向phrack致敬!)          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              <--------------------------( Table of Contents )-------------------------->          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">               0x01  变量的结构和类型          </p>          <p class="sycode">               0x02  哈希表--PHP的灵魂          </p>          <p class="sycode">               0x03  常量          </p>          <p class="sycode">               0x04  参考文献          </p>          <p class="sycode">              <------------------------------------------------------------------------->          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              0x01  变量的结构和类型          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              1.数据类型          </p>          <p class="sycode">                1.1静态类型语言(C/Java),编译时确定          </p>          <p class="sycode">                1.2动态类型语言(php/python),运行时确定          </p>          <p class="sycode">                1.3无类型语言(汇编),操作的底层存储          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              2.php内核中所有的变量使用同一种数据结构zval来保存,而这个结构同时表示php中各种数据类型,它不仅仅包含变量的值,也包含变量的类型。这就是php弱类型的核心。          </p>          <p class="sycode">                      php中的8中数据类型:          </p>          <p class="sycode">                2.1标量类型: boolean, integer, float, string          </p>          <p class="sycode">                2.2复合类型:  array, object          </p>          <p class="sycode">                2.3特殊类型: resource, null          </p>          <p class="sycode">                          </p>          <p class="sycode">              3.zval结构体(在php源码目录下Zend/zend.h中定义):          </p>          <p class="sycode">                struct _zval_struct{          </p>          <p class="sycode">                	  /*Variable information*/          </p>          <p class="sycode">                	  zvalue_value value  	/*value, 变量的值*/          </p>          <p class="sycode">                	  zend_uint refcount__gc  /*reference count, 引用计数器*/          </p>          <p class="sycode">                	  zend_uchar type 		/*active type, 变量的类型*/          </p>          <p class="sycode">                	  zend_uchar is_ref__gc;  /*变量是否被引用*/          </p>          <p class="sycode">                }          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              4.变量类型:          </p>          <p class="sycode">                /*data types */          </p>          <p class="sycode">                #define IS_NULL		0           </p>          <p class="sycode">                #define IS_LONG 		1          </p>          <p class="sycode">                #define IS_DOUBLE 	2          </p>          <p class="sycode">                #define IS_BOOL 		3          </p>          <p class="sycode">                #define IS_ARRAY		4          </p>          <p class="sycode">                #define IS_OBJECT		5          </p>          <p class="sycode">                #define IS_STRING 	6          </p>          <p class="sycode">                #define IS_RESOURCE	7          </p>          <p class="sycode">                #define IS_CONSTANT	8          </p>          <p class="sycode">                #define IS_CONSTANT_ARRAY	9          </p>          <p class="sycode">                #define IS_CALLABLE	10          </p>          <p class="sycode">                          </p>          <p class="sycode">              5.变量的值存储          </p>          <p class="sycode">                typedef union _zvalue_value {          </p>          <p class="sycode">                    long lval; 		/*long、bool、resource类型*/          </p>          <p class="sycode">              	  double dval ;	/*double 类型*/          </p>          <p class="sycode">              	  struct {		/*string 类型, len保存了字符串的长度*/          </p>          <p class="sycode">              	  	char *val;          </p>          <p class="sycode">              	  	int len;          </p>          <p class="sycode">              	  } str;          </p>          <p class="sycode">              	  HashTable *ht;  /*数组, 用HashTable实现*/          </p>          <p class="sycode">              	  zend_object_value obj; /*object 类型*/          </p>          <p class="sycode">                } zvalue_value;          </p>          <p class="sycode">                          </p>          <p class="sycode">                这里之所以用共同体(union)是因为一个变量只可能有一种类型,符合共同体的特性,如果使用结构体则会浪费内存。          </p>          <p class="sycode">                          </p>          <p class="sycode">                实例:创建一个值为10的整型变量lvar,用php脚本的话很简单,就是:$lvar = 10          </p>          <p class="sycode">                而PHP内核中的实现可能就是类似下面这样:          </p>          <p class="sycode">                zval lval;          </p>          <p class="sycode">                Z_TYPE(lvar) = IS_LONG;          </p>          <p class="sycode">                Z_LVAL(lvar) = 10;          </p>          <p class="sycode">                          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              0x02  哈希表--PHP的灵魂          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              1.为什么用哈希表          </p>          <p class="sycode">                哈希表通常提供CRUD(Create, Read, Update, Delete)操作,设计合理的哈希表中,这些操作时间复杂度为O(1),这也是它被钟爱的原因。          </p>          <p class="sycode">                hash(key) -> index          </p>          <p class="sycode">                          </p>          <p class="sycode">              2.哈希表的实现:结构体 bucket和_hashtable组成了完整的HashTable。          </p>          <p class="sycode">                首先看bucket结构体(定义在 Zend/zend_hash.h):          </p>          <p class="sycode">                typedef struct bucket {          </p>          <p class="sycode">              	  ulong h;  					/*hash值*/          </p>          <p class="sycode">              	  uint nKeyLength;			/*key的长度*/          </p>          <p class="sycode">              	  void *pData;				/*要保存的内存块地址,通常是malloc来的地址*/          </p>          <p class="sycode">              	  void *pDataPtr;				/*保存指针数据,不经过malloc的指针,防止产生内存碎片*/          </p>          <p class="sycode">              	  struct bucket *pListNext;   /*bucket中具有同一hash值的下一个元素*/          </p>          <p class="sycode">              	  struct bucket *pListLast;   /*bucket中具有同一hash值的上一个元素*/          </p>          <p class="sycode">              	  struct bucket *pNext;		/*双向链表的下一个元素*/          </p>          <p class="sycode">              	  struct bucket *pLast;       /*双向链表的上一个元素*/          </p>          <p class="sycode">              	  const char *arKey;			/*保存key*/          </p>          <p class="sycode">                } Bucket;          </p>          <p class="sycode">                          </p>          <p class="sycode">                可以看出bucket是一个双向链表,这是为了解决多个key冲突的问题(即算法导论中的链接法)          </p>          <p class="sycode">                          </p>          <p class="sycode">                          </p>          <p class="sycode">                再看_hashtable结构体:          </p>          <p class="sycode">                typedef struct _hashtable {          </p>          <p class="sycode">                    uint nTableSize;                /*bucket数组的大小*/          </p>          <p class="sycode">              	  uint nTableMask;				          </p>          <p class="sycode">              	  uint nNumOfElements;			/*HashTable中元素的个数*/          </p>          <p class="sycode">              	  ulong nNextFreeElement;			/*下一个可用的Bucket位置*/          </p>          <p class="sycode">              	  Bucket *pInternalPointer		/*遍历HashTable元素*/          </p>          <p class="sycode">              	  Bucket *pListHead;				/*双向链表表头*/          </p>          <p class="sycode">              	  Bucket *pListTail;				/*双向链表表尾*/          </p>          <p class="sycode">              	  Bucket **arBuckets;				/*Bucket数组*/          </p>          <p class="sycode">                } HashTable;          </p>          <p class="sycode">                          </p>          <p class="sycode">                ========          </p>          <p class="sycode">                此处为HashTable的结构图          </p>          <p class="sycode">                ========          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              3.神奇的数字--33          </p>          <p class="sycode">                见我原来的一篇博客:http://blog.csdn.net/wusuopubupt/article/details/11479869          </p>          <p class="sycode">                下面是PHP源码中的一段注释:          </p>          <p class="sycode">                /*          </p>          <p class="sycode">                 * DJBX33A (Daniel J. Bernstein, Times 33 with Addition)          </p>          <p class="sycode">                 *          </p>          <p class="sycode">                 * This is Daniel J. Bernstein's popular `times 33' hash function as          </p>          <p class="sycode">                 * posted by him years ago on comp.lang.c. It basically uses a function          </p>          <p class="sycode">                 * like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best          </p>          <p class="sycode">                 * known hash functions for strings. Because it is both computed very          </p>          <p class="sycode">                 * fast and distributes very well.          </p>          <p class="sycode">                 *          </p>          <p class="sycode">                 * The magic of number 33, i.e. why it works better than many other          </p>          <p class="sycode">                 * constants, prime or not, has never been adequately explained by          </p>          <p class="sycode">                 * anyone. So I try an explanation: if one experimentally tests all          </p>          <p class="sycode">                 * multipliers between 1 and 256 (as RSE did now) one detects that even          </p>          <p class="sycode">                 * numbers are not useable at all. The remaining 128 odd numbers          </p>          <p class="sycode">                 * (except for the number 1) work more or less all equally well. They          </p>          <p class="sycode">                 * all distribute in an acceptable way and this way fill a hash table          </p>          <p class="sycode">                 * with an average percent of approx. 86%.          </p>          <p class="sycode">                 *          </p>          <p class="sycode">                 * If one compares the Chi^2 values of the variants, the number 33 not          </p>          <p class="sycode">                 * even has the best value. But the number 33 and a few other equally          </p>          <p class="sycode">                 * good numbers like 17, 31, 63, 127 and 129 have nevertheless a great          </p>          <p class="sycode">                 * advantage to the remaining numbers in the large set of possible          </p>          <p class="sycode">                 * multipliers: their multiply operation can be replaced by a faster          </p>          <p class="sycode">                 * operation based on just one shift plus either a single addition          </p>          <p class="sycode">                 * or subtraction operation. And because a hash function has to both          </p>          <p class="sycode">                 * distribute good _and_ has to be very fast to compute, those few          </p>          <p class="sycode">                 * numbers should be preferred and seems to be the reason why Daniel J.          </p>          <p class="sycode">                 * Bernstein also preferred it.          </p>          <p class="sycode">                 *          </p>          <p class="sycode">                 *          </p>          <p class="sycode">                 *                  -- Ralf S. Engelschall <rse@engelschall.com>          </p>          <p class="sycode">                 */          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">                          </p>          <p class="sycode">              4.哈希表的操作接口(省略了部分参数)          </p>          <p class="sycode">                初始化HashTable:int _zend_hash_init(HashTable *ht, uint nSize, hash_func_t pHashFunction);          </p>          <p class="sycode">                添加新hash值:   int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData)          </p>          <p class="sycode">                查找hash:       int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              0x03  常量          </p>          <p class="sycode">              /////           </p>          <p class="sycode">              1.常量的内部结构          </p>          <p class="sycode">                typedef struct _zend_constant {          </p>          <p class="sycode">              	  zval value;          </p>          <p class="sycode">              	  int flags;  /*常量标记,如 CONST_PERSISTENT | CONST_CS */          </p>          <p class="sycode">              	  char *name;          </p>          <p class="sycode">              	  uint name_len;          </p>          <p class="sycode">              	  int module_number;          </p>          <p class="sycode">                } zend_constant;          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              2.define定义常量的过程            </p>          <p class="sycode">                define的实现(定义在Zend/zend_builtin_functions.c),下面是部分核心代码:          </p>          <p class="sycode">                          </p>          <p class="sycode">                ZEND_FUNCTION(define)          </p>          <p class="sycode">                {          </p>          <p class="sycode">                    /* 检查常量名是否存在 */          </p>          <p class="sycode">                    if (zend_memnstr(name, "::", sizeof("::") - 1, name + name_len)) {          </p>          <p class="sycode">                        zend_error(E_WARNING, "Class constants cannot be defined or redefined");          </p>          <p class="sycode">                        RETURN_FALSE;          </p>          <p class="sycode">                    }          </p>          <p class="sycode">                              </p>          <p class="sycode">                    ... // 类常量定义 此处不做介绍          </p>          <p class="sycode">                              </p>          <p class="sycode">                    c.value = *val;          </p>          <p class="sycode">                    zval_copy_ctor(&c.value);          </p>          <p class="sycode">                    if (val_free) {          </p>          <p class="sycode">                            zval_ptr_dtor(&val_free);          </p>          <p class="sycode">                    }          </p>          <p class="sycode">                    c.flags = case_sensitive;  /* 大小写敏感 */          </p>          <p class="sycode">                    c.name = zend_strndup(name, name_len);          </p>          <p class="sycode">                    c.name_len = name_len+1;          </p>          <p class="sycode">                    c.module_number = PHP_USER_CONSTANT;          </p>          <p class="sycode">                    if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {  /*注册常量*/          </p>          <p class="sycode">                            RETURN_TRUE;          </p>          <p class="sycode">                    } else {          </p>          <p class="sycode">                            RETURN_FALSE;          </p>          <p class="sycode">                    }          </p>          <p class="sycode">                }          </p>          <p class="sycode">                          </p>          <p class="sycode">              3.魔术常量          </p>          <p class="sycode">                PHP中的魔术常量,虽然叫做常量,但它们的值实际上随它们在代码中的位置而变化的。          </p>          <p class="sycode">                __LINE__	 	文件中的当前行号。          </p>          <p class="sycode">                __FILE__	 	文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。          </p>          <p class="sycode">                __DIR__	 	文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。它等价于 dirname(__FILE__)。          </p>          <p class="sycode">                __FUNCTION__	函数名称          </p>          <p class="sycode">                __CLASS__	 	类的名称。类名包括其被声明的作用区域(例如 Foo\Bar)。          </p>          <p class="sycode">                __TRAIT__	 	Trait 的名字。Trait 名包括其被声明的作用区域(例如 Foo\Bar)。          </p>          <p class="sycode">                __METHOD__	类的方法名          </p>          <p class="sycode">                __NAMESPACE__	当前命名空间的名称(区分大小写)。此常量是在编译时定义的(PHP 5.3.0 新增)。          </p>          <p class="sycode">                          </p>          <p class="sycode">                PHP内核会在词法解析时将这些常量的内容赋值进行替换,而不是在运行时进行分析。 举个例子:          </p>          <p class="sycode">                <?php          </p>          <p class="sycode">                echo __LINE__;          </p>          <p class="sycode">                function demo() {          </p>          <p class="sycode">                  echo __FUNCTION__;          </p>          <p class="sycode">                }          </p>          <p class="sycode">                demo();          </p>          <p class="sycode">                ?>          </p>          <p class="sycode">                PHP已经在词法解析时将这些常量换成了对应的值,以上的代码可以看成如下的PHP代码:          </p>          <p class="sycode">                <?php          </p>          <p class="sycode">                echo 2;          </p>          <p class="sycode">                function demo() {          </p>          <p class="sycode">                    echo "demo";          </p>          <p class="sycode">                }          </p>          <p class="sycode">                demo();          </p>          <p class="sycode">                ?>          </p>          <p class="sycode">              <br>          </p>          <p class="sycode">                ===========          </p>          <p class="sycode">                此处涉及编译原理知识,需补充。          </p>          <p class="sycode">                ===========          </p>          <p class="sycode">                          </p>          <p class="sycode">              /////          </p>          <p class="sycode">              0x04  参考文献          </p>          <p class="sycode">              /////           </p>          <p class="sycode">              <br>          </p>          <p class="sycode">              TIPI: http://www.php-internals.com/book/?p=chapt03/03-00-variable-and-data-types          </p>

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 18万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 3.7万人学习

NumPy 教程
NumPy 教程

共44课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号