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

  1. <?php
  2. $var = 1; //int
  3. $var = "laruence"; //string
  4. $var = 1.0002; //float
  5. $var = array(); // array
  6. $var = new Exception('error'); //object;

动态语言,就是说,PHP的语言结构在运行期是可以改变的,比如我们在运行期require一个函数定义文件,从而导致语言的函数表动态的改变。
所谓脚本语言,就是说,PHP并不是独立运行的,要运行PHP我们需要PHP解析器:

  1. /usr/bin/php -f example.php

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

首先要声明一点,如果你以前没有接触过PHP的源码分析,扩展开发。 如果你并不了解PHP的架构, 没有听说ZE,那么我建议你先看看我前面的文章,尤其推荐:

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

  1. typedef struct _zval_struct {
  2. zvalue_value value;
  3. zend_uint refcount;
  4. zend_uchar type;
  5. zend_uchar is_ref;
  6. } zval;

其中zvalue_value是真正保存数据的关键部分,现在到了揭晓谜底的时候了,PHP是如何在ZE的基础上实现弱类型的呢? 因为zvalue_value是个联合体(union),

  1. typedef union _zvalue_value {
  2. long lval;
  3. double dval;
  4. struct {
  5. char *val;
  6. int len;
  7. } str;
  8. HashTable *ht;
  9. zend_object_value obj;
  10. } zvalue_value;

那么这个结构是如何储存PHP中的多种类型的呢?
PHP中常见的变量类型有:

  1. 1. 整型/浮点/长整型/bool值 等等
  2. 2. 字符串
  3. 3. 数组/关联数组
  4. 4. 对象
  5. 5. 资源

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

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

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

  1. zval.type = IS_STRING

这个时候,就会取:
zval.value.str
而这个也是个结构,存有C分格的字符串和字符串的长度。

而对于数组和对象,则type分别对应IS_ARRAY, IS_OBJECT, 相对应的则分别取zval.value.ht和obj

比较特别的是资源,在PHP中,资源是个很特别的变量,任何不属于PHP内建的变量类型的变量,都会被看作成资源来进行保存,比如,数据库句柄,打开的文件句柄等等。 对于资源:

  1. type = IS_RESOURCE

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

  1. ZEND_FETCH_RESOURCE(con, type, zval *, default, resource_name, resource_type);

借用这样的机制,PHP就实现了弱类型,因为对于ZE的来说,它所面对的永远都是同一种类型,那就是zval。
ps:明天team出去building,我想着应该在走之前写点东西给我的blog reader来消磨周末。今天就简单先开个头,下一次,我将进一步介绍PHP的变量,作用域,以及变量的copy on write和change on write机制, 待续….

PHP原理之对象(一)的更多相关文章

  1. iOS Category 添加属性实现原理 - 关联对象

    iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...

  2. AOP之proceedingjoinpoint和joinpoint区别(获取各对象备忘)、动态代理机制及获取原理代理对象、获取Mybatis Mapper接口原始对象

    现在AOP的场景越来越多,所以我们有必要理解下和AOP相关的一些概念和机制. import org.aspectj.lang.reflect.SourceLocation; public interf ...

  3. 构造函数原理 - Js对象

    构造函数内部原理 有new之后,函数变成构造函数,产生三步隐式变化 1.函数执行,在函数体顶端隐式加上var this = {}; 2.执行赋值,AO{ this : {name:'zhangsan' ...

  4. 转载:Javascript面向对象编程原理 -- 理解对象

    源地址:http://www.html-js.com/article/1717 虽然JavaScript中已经自带了很多内建引用类型,你还是会很频繁的需要创建自己的对象.JavaScript编程的很大 ...

  5. java-异常-原理异常对象的抛出throw

    1 class Demo { 2 public static int method(int[] arr,int index) { 3 4 // System.out.println(arr[index ...

  6. 基于Apache组件,分析对象池原理

    池塘里养:Object: 一.设计与原理 1.基础案例 首先看一个基于common-pool2对象池组件的应用案例,主要有工厂类.对象池.对象三个核心角色,以及池化对象的使用流程: import or ...

  7. Struts 2 Spring Hibernate三大框架的执行流程以及原理

    Struts2框架 一.简介 Struts2是一个相当强大的Java Web开源框架,是一个基于POJO的Action的MVC Web框架.它基于当年的WebWork和XWork框架,继承其优点,同时 ...

  8. JavaScript对象中的属性(可写,可配置,可枚举,value,getter,setter)

    JavaScript中,对象包括3个特性,分别为,可扩展性,class标识符,属性. 如果对象的可扩展性为false,则不可为对象动态的添加属性.   对象包含分为存取器属性和值属性.存取属性为 {g ...

  9. C#对象的深拷贝与浅拷贝

    转载自:http://blog.163.com/hr_msn/blog/static/21549405120132250396584/ 深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会 ...

随机推荐

  1. 「HTML5」url、href、src区别

    一.URL的概念 统一资源定位符(或称统一资源定位器/定位地址.URL地址等,英语:Uniform Resource Locator,常缩写为URL),有时也被俗称为网页地址(网址).如同在网络上的门 ...

  2. [DeeplearningAI笔记]序列模型2.10词嵌入除偏

    5.2自然语言处理 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.10词嵌入除偏 Debiasing word embeddings Bolukbasi T, Chang K W, Zo ...

  3. jq的图片放大镜效果

    <div class="imgbox"> <div class="probox"> <img src="" a ...

  4. js闭包及问题的解决

    闭包定义,作用 闭包就是能够读取其他函数内部变量的函数. 作用:一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中 缺点:闭包会保存函数中的变量在内存中,导致内存消耗大   闭包会 ...

  5. poj 3164 Command Network(最小树形图模板)

    Command Network http://poj.org/problem?id=3164 Time Limit: 1000MS   Memory Limit: 131072K Total Subm ...

  6. 树链剖分处理+线段树解决问题 HDU 5029

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5029 题意:n个点的树,m次操作.每次操作输入L,R,V,表示在[L,R]这个区间加上V这个数字.比 ...

  7. ZOJ 3777 B - Problem Arrangement 状压DP

    LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 题意:有N(\( N <= 12 \))道题,排顺序 ...

  8. Java学习遇到的问题

    一. Java中泛型如何比较大小,继承Comparable类,然后实现其唯一的方法compareTo(): public class GenericClass<E extends Compara ...

  9. 分享一个数据库sql_mode 引起的坑

    sql_mode坑 MySQL 5.7.x 默认值: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR ...

  10. 基本控件文档-UIView属性---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 //转载请注明出处--本文永久链接:http://www.cnblogs.com/Ch ...