浅析PHP原理之变量(Variables inside PHP)


Posted in PHP onAugust 09, 2013

或许你知道,或许你不知道,PHP是一个弱类型,动态的脚本语言。所谓弱类型,就是说PHP并不严格验证变量类型(严格来讲,PHP是一个中强类型语言,这部分内容会在以后的文章中叙述),在申明一个变量的时候,并不需要显示指明它保存的数据的类型:

<?php
  $var = 1; //int
  $var = "laruence"; //string
  $var = 1.0002; //float
  $var = array(); // array
  $var = new Exception('error'); //object;

动态语言,就是说,PHP的语言结构在运行期是可以改变的,比如我们在运行期require一个函数定义文件,从而导致语言的函数表动态的改变。

所谓脚本语言,就是说,PHP并不是独立运行的,要运行PHP我们需要PHP解析器:

  /usr/bin/php -f example.ph

我前面的文章中已经讲过,PHP的执行是通过Zend engine(ZE, Zend引擎), ZE是用C编写的,大家都知道C是一个强类型语言,也就是说,在C中所有的变量在它被声明到最终销毁,都只能保存一种类型的数据。 那么PHP是如何在ZE的基础上实现弱类型的呢?

在PHP中,所有的变量都是用一个结构-zval来保存的, 在Zend/zend.h中我们可以看到zval的定义:

  typedef struct _zval_struct {
    zvalue_value value;
    zend_uint refcount;
    zend_uchar type;
    zend_uchar is_ref;
  } zval;
 
其中zvalue_value是真正保存数据的关键部分,现在到了揭晓谜底的时候了,PHP是如何在ZE的基础上实现弱类型的呢? 因为zvalue_value是个联合体(union),
typedef union _zvalue_value {
    long lval;
    double dval;
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;
    zend_object_value obj;
} zvalue_value;

那么这个结构是如何储存PHP中的多种类型的呢?

PHP中常见的变量类型有:
1. 整型/浮点/长整型/bool值 等等
2. 字符串
3. 数组/关联数组
4. 对象
5. 资源

PHP根据zval中的type字段来储存一个变量的真正类型,然后根据type来选择如何获取zvalue_value的值,比如对于整型和bool值:

   zval.type = IS_LONG;//整形
   zval.type = IS_BOOL;//布尔

就去取zval.value.lval,对于bool值来说lval∈(0|1);
如果是双精度,或者float则会去取zval.value的dval。
而如果是字符串,那么:
   zval.type = IS_STRIN

这个时候,就会取:
zval.value.str
而这个也是个结构,存有C分格的字符串和字符串的长度。
而对于数组和对象,则type分别对应IS_ARRAY, IS_OBJECT, 相对应的则分别取zval.value.ht和obj
比较特别的是资源,在PHP中,资源是个很特别的变量,任何不属于PHP内建的变量类型的变量,都会被看作成资源来进行保存,比如,数据库句柄,打开的文件句柄等等。 对于资源:
   type = IS_RESOURC

这个时候,会去取zval.value.lval, 此时的lval是个整型的指示器, 然后PHP会再根据这个指示器在PHP内建的一个资源列表中查询相对应的资源(这部分的内容,我以后会单独开一个篇文章来介绍),目前,你只要知道此时的lval就好像是对应于资源链表的偏移值。
 ZEND_FETCH_RESOURCE(con, type, zval *, default, resource_name, resource_type);

借用这样的机制,PHP就实现了弱类型,因为对于ZE的来说,它所面对的永远都是同一种类型,那就是zval。
PHP 相关文章推荐
PHP 和 MySQL 开发的 8 个技巧
Jan 02 PHP
php循环输出数据库内容的代码
May 24 PHP
PHPMyAdmin 快速配置方法
May 11 PHP
php 空格,换行,跳格使用说明
Dec 18 PHP
PHP_Cooikes不同页面无法传递的解决方法
Mar 07 PHP
PHP 面向对象程序设计(oop)学习笔记 (五) - PHP 命名空间
Jun 12 PHP
CI框架Session.php源码分析
Nov 03 PHP
php提交表单发送邮件的方法
Mar 20 PHP
php实现用于验证所有类型的信用卡类
Mar 24 PHP
YII CLinkPager分页类扩展增加显示共多少页
Jan 29 PHP
ThinkPHP 3使用OSS的方法
Jul 19 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 PHP
浅析PHP原理之变量分离/引用(Variables Separation)
Aug 09 #PHP
php中如何使对象可以像数组一样进行foreach循环
Aug 09 #PHP
php接口与接口引用的深入解析
Aug 09 #PHP
解析数组非数字键名引号的必要性
Aug 09 #PHP
php防注入及开发安全详细解析
Aug 09 #PHP
分割GBK中文遭遇乱码的解决方法
Aug 09 #PHP
解析isset与is_null的区别
Aug 09 #PHP
You might like
php检测useragent版本示例
2014/03/24 PHP
php实现遍历多维数组的方法
2015/11/25 PHP
PHP7 新增功能
2021/03/09 PHP
基于jQuery的淡入淡出可自动切换的幻灯插件
2010/08/24 Javascript
解决jquery异步按一定的时间间隔刷新问题
2012/12/10 Javascript
网页加载时页面显示进度条加载完成之后显示网页内容
2012/12/23 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
JavaScript中的Function函数
2015/08/27 Javascript
详解JS中Array对象扩展与String对象扩展
2016/01/07 Javascript
详解Bootstrap的iCheck插件checkbox和radio
2016/08/24 Javascript
jQuery+CSS3实现四种应用广泛的导航条制作实例详解
2016/09/17 Javascript
老生常谈js中的MVC
2017/07/25 Javascript
分析JS中this引发的bug
2017/12/12 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
Ant Design Pro 下实现文件下载的实现代码
2019/12/03 Javascript
详解小程序横屏方案对比
2020/06/28 Javascript
JS实现多功能计算器
2020/10/28 Javascript
python之wxPython应用实例
2014/09/28 Python
在python win系统下 打开TXT文件的实例
2018/04/29 Python
Python 查看list中是否含有某元素的方法
2018/06/27 Python
Python中的集合介绍
2019/01/28 Python
Python实现生成密码字典的方法示例
2019/09/02 Python
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
La Senza官网:北美顶尖性感内衣品牌
2018/08/03 全球购物
校园歌手大赛策划书
2014/01/17 职场文书
《中国的气候》教学反思
2014/02/23 职场文书
品牌服务方案
2014/06/03 职场文书
搞笑的获奖感言
2014/08/16 职场文书
幼儿园教师节演讲稿
2014/09/03 职场文书
离婚协议书怎样才有法律效力
2014/10/10 职场文书
中班下学期幼儿评语
2014/12/30 职场文书
心理健康教育主题班会
2015/08/13 职场文书
利用JuiceFS使MySQL 备份验证性能提升 10 倍
2022/03/17 MySQL
vue3引入highlight.js进行代码高亮的方法实例
2022/04/08 Vue.js
MySQL中的全表扫描和索引树扫描
2022/05/15 MySQL