PHP类型
PHP类型基础知识
PHP是弱类型语言(依照laruence的说法是一种中强类型语言)
所谓的弱类型就是在申明一个变量的时候,并不需要显式指明它保存的数据的类型,在程序执行的过程中可以根据需求动态的改变变量的类型.
那PHP是如何实现这个功能的呢?
首先PHP定义了一个保存变量的结构体(C语言)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| typedef struct _zval_struct zval; typedef union _zvalue_value { long lval; double dval; struct { char *val; int len; } str; HashTable *ht; zend_object_value obj; zend_ast *ast; } zvalue_value; struct _zval_struct { zvalue_value value; zend_uint refcount__gc; zend_uchar type; zend_uchar is_ref__gc; };
|
保存变量的地方是_zvalue_value,_zvalue_value定义了一个联合体①来储存用户输入的变量
_zvalue_value可以把内存中的值相对应的解释为long、double、str等类型,比较特殊的有三种HashTable *ht(数组)、obj(对象)和*ast(资源)
这个变量是什么类型由zend_uchar type; /* active type */决定,
type的种类在Zend/zend.h:583-601中定义.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| /* data types */ /* All data types <= IS_BOOL have their constructor/destructors skipped */ #define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_BOOL 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_STRING 6 #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_AST 9 #define IS_CALLABLE 10 #define IS_CONSTANT_TYPE_MASK 0x00f #define IS_CONSTANT_UNQUALIFIED 0x010 #define IS_LEXICAL_VAR 0x020 #define IS_LEXICAL_REF 0x040 #define IS_CONSTANT_IN_NAMESPACE 0x100 #define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
|
PHP中实现转换就是当zval.type = IS_LONG是,就把结构体里的value转换成long型,当zval.type = IS_STRING时,就把结构体里面的value转换成str类型
明白了以上基础知识就可以来探究zval.type会在哪些场景带来哪些问题了.
①为什么要用联合体呢?
在K&R的<<Pointer on C>>中我们可以翻阅到这么一段文字
1
| 联合的声明和结构类似,但它的行为方式却和结构不同.联合的所有成员引用的是内存中相同的位置.当你想在不同的时刻把不同的东西储存在同一个位置的时候,就可以使用联合.
|
联合体可以用来动态的表示同一个内存中的值的类型.假如使用结构体来储存用户输入地变量的话,那么假设用户输入了1,如果想要把1以char,int,double等等来表示的话,就会成倍的增加内存占用.