浅析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 相关文章推荐
swfupload 多文件上传实现代码
Aug 27 PHP
php压缩多个CSS为一个css的代码并缓存
Apr 21 PHP
关于UEditor编辑器远程图片上传失败的解决办法
Aug 31 PHP
php图片加中文水印实现代码分享
Oct 31 PHP
php不允许用户提交空表单(php空值判断)
Nov 12 PHP
ThinkPHP关于session的操作方法汇总
Jul 18 PHP
基于PHP微信红包的算法探讨
Jul 21 PHP
php加密解密字符串示例
Oct 13 PHP
PHP微信PC二维码登陆的实现思路
Jul 13 PHP
使用PHP访问RabbitMQ消息队列的方法示例
Jun 06 PHP
在laravel-admin中列表中禁止某行编辑、删除的方法
Oct 03 PHP
php 中的信号处理操作实例详解
Mar 04 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实现百度网盘图片直链的代码分享
2012/11/01 PHP
PHP多线程批量采集下载美女图片的实现代码(续)
2013/06/03 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
php将日期格式转换成xx天前的格式
2015/04/16 PHP
thinkphp集成前端脚手架Vue-cli的教程图解
2018/08/30 PHP
修改发贴的编辑功能
2007/03/07 Javascript
jquery 图片 上一张 下一张 链接效果(续篇)
2010/04/20 Javascript
JavaScript高级程序设计(第3版)学习笔记7 js函数(上)
2012/10/11 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
轻松创建nodejs服务器(8):非阻塞是如何实现的
2014/12/18 NodeJs
xmlplus组件设计系列之选项卡(Tabbar)(5)
2017/05/03 Javascript
详解React+Koa实现服务端渲染(SSR)
2018/05/23 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
vue简单练习 桌面时钟的实现代码实例
2019/09/19 Javascript
vue 移动端记录页面浏览位置的方法
2020/03/11 Javascript
实用的 vue tags 创建缓存导航的过程实现
2020/12/03 Vue.js
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
[01:14:55]EG vs Spirit Supermajor 败者组 BO3 第三场 6.4
2018/06/05 DOTA
详解用python自制微信机器人,定时发送天气预报
2019/03/25 Python
python 读取修改pcap包的例子
2019/07/23 Python
用python制作个视频下载器
2021/02/01 Python
Steve Madden官网:美国鞋类品牌
2017/01/29 全球购物
Expedia挪威官网:酒店、机票和租车
2018/03/03 全球购物
Lovedrobe官网:英国领先的大码服装品牌
2019/09/19 全球购物
计算机科学与技术应届生求职信
2013/11/07 职场文书
制药工程专业个人求职自荐信
2014/01/25 职场文书
经贸专业毕业生求职信范文
2014/05/01 职场文书
大学生标准自荐书
2014/06/15 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
大专生自荐书范文
2014/06/22 职场文书
作风转变心得体会
2014/09/02 职场文书
放飞理想演讲稿
2014/09/09 职场文书
三八妇女节慰问信
2015/02/14 职场文书
月考总结与反思
2015/10/22 职场文书
实战 快速定位MySQL的慢SQL
2022/03/22 MySQL
python如何为list实现find方法
2022/05/30 Python