php内核简析

变量zval

php变量是一个zval结构体,包含引用计数、活动类型、是否为引用、和zvalue_value的结构体。zvalue_value是一个联合结构,包括长整数long、浮点数double、字符串、数组哈希表HashTable、和对象值结构zend_object_value。其中ht为数组,obj为对象,resource使用lval为句柄。

typedef union _zvalue_value {

       long lval;                            

       double dval;                        

       struct {

              char *val;

              int len;

       } str;

       HashTable *ht;                           

       zend_object_value obj;

} zvalue_value;

struct _zval_struct {

      

       zvalue_value value;             

       zend_uint refcount;

       zend_uchar type;   

       zend_uchar is_ref;

};

typedef struct _zval_struct zval;

 

数组和哈希表

HashTable哈希表是包含一组哈希表结构和函数,其最大的为0x80000000,bucket是指针链接表,arKey为Key,pData为数据的指针,hashtable为主表,arBuckets为bucket指针数组,结构如下:

typedef struct bucket {

       ulong h;                                    

       uint nKeyLength;

       void *pData;

       void *pDataPtr;

       struct bucket *pListNext;

       struct bucket *pListLast;

       struct bucket *pNext;

       struct bucket *pLast;

       char arKey[1];

} Bucket;

typedef struct _hashtable {

       uint nTableSize;

       uint nTableMask;

       uint nNumOfElements;

       ulong nNextFreeElement;

       Bucket *pInternalPointer;     

       Bucket *pListHead;

       Bucket *pListTail;

       Bucket **arBuckets;

       dtor_func_t pDestructor;

       zend_bool persistent;

       unsigned char nApplyCount;

       zend_bool bApplyProtection;

} HashTable;

 

对象和类

php对象值结构zend_object_value是一个包含对象句柄zend_object_handle、zend_object_handlers的指针,zend_object_handlers包含一组操作对象的函数,如引用计数(add_ref、del_ref)和其它函数(clone_obj、read_property、write_property、has_property、unset_property、get_properties、get_method、call_method、get_constructor、cast_object、get_class_name、count_elements等)。对象句柄zend_object_handle是objects_store中对象存储池store bulk的索引。

php对象zend_object包括类结构,和一个属性properties的哈希表。类结构zend_class_entry包括类型,名称,父类指针,引用计数,文件名,模块结构指针,(方法、属性默认值、属性信息、默认静态成员、静态成员、常量、函数)的哈希表,和一组系统方法(construct、destructor、clone、__get、__set、__unset、__isset、__call、__tostring、serialize_func、unserialize_func),以及接口结构。类析构当引用计数等于0,将释放属性默认值、属性信息,常量、函数等的哈希表和接口结构。

typedef struct _zend_object_value {

       zend_object_handle handle;

       zend_object_handlers *handlers;

} zend_object_value;

typedef struct _zend_object {

       zend_class_entry *ce;

       HashTable *properties;

} zend_object;

struct _zend_class_entry {

       char type;

       char *name;

       zend_uint name_length;

       struct _zend_class_entry *parent;

       int refcount;

 

       HashTable function_table;

       HashTable default_properties;

       HashTable properties_info;

       HashTable default_static_members;

       HashTable *static_members;

       HashTable constants_table;

       struct _zend_function_entry *builtin_functions;

 

       union _zend_function *constructor;

       union _zend_function *destructor;

       union _zend_function *clone;

       union _zend_function *__get;

       union _zend_function *__set;

       union _zend_function *__unset;

       union _zend_function *__isset;

       union _zend_function *__call;

       union _zend_function *__tostring;

       union _zend_function *serialize_func;

       union _zend_function *unserialize_func;

 

       zend_class_entry **interfaces;

       zend_uint num_interfaces;

 

       char *filename;

       zend_uint line_start;

       zend_uint line_end;

       char *doc_comment;

       zend_uint doc_comment_len;

       struct _zend_module_entry *module;

};

typedef struct _zend_property_info {

       zend_uint flags;

       char *name;

       int name_length;

       ulong h;

       char *doc_comment;

       int doc_comment_len;

       zend_class_entry *ce;

} zend_property_info;

资源resource

资源resource使用zval中lval为句柄,资源存储在全局变量HashTable regular_list,持久资源存储在全局变量persistent_list,资源句柄是regular_list的索引index,资源使用zend_rsrc_list_entry结构存储,如果引用计数refcount等于0,将资源存储列表regular_list、persistent_list对应的资源zend_rsrc_list_entry删除,同时释放资源。释放资源时,找到对应的析构方法,释放对应的内容,持久资源使用其持久资源对应的析构方法。资源模块一般带有资源和持久资源两种析构方法。

typedef struct _zend_rsrc_list_entry {

       void *ptr;

       int type;

       int refcount;

} zend_rsrc_list_entry;

 

常量

常量存储在全局变量HashTable *zend_constants,常量以zend_constant结构注册到zend_constants中,注册常量时常量名称将转换为小写,故php常量大小写不敏感。查找常量时,首先查找类常量,即classname::constname,如果有效将查找类的常量表,否则查找全局变量zend_constants哈希表的内容。系统设定的常量除错误类型常量外,还有TRUE,FALSE,NULL,ZEND_THREAD_SAFE。

typedef struct _zend_constant {

       zval value;

       int flags;

       char *name;

       uint name_len;

       int module_number;

} zend_constant;

内置函数

Php内置函数包括:zend_version,func_num_args,func_get_arg,func_get_args,strlen,strcmp,strncmp,strcasecmp,strncasecmp,each,error_reporting,define,defined,get_class,get_parent_class,method_exists,property_exists,class_exists,interface_exists,function_exists,get_included_files,is_subclass_of,is_a,get_class_vars,get_object_vars,get_class_methods,trigger_error,set_error_handler,restore_error_handler,set_exception_handler,restore_exception_handler,get_declared_classes,get_declared_interfaces,get_defined_functions,get_defined_vars ,get_loaded_extensions ,extension_loaded,get_resource_type ,get_extension_funcs,get_defined_constants,create_function。

函数

函数参数获取通过参数栈顶部得到,函数注册在全局变量function_table中,一般类方法或者类静态方法,首先在类中,然后在父类中查找,在全局函数表中查找,检查方法是否可用(如是否为抽象方法、过时方法),将参数压入参数栈,设置符号表和范围,设置返回值和中间代码,执行代码,如果是内部函数,直接调用。

typedef struct _zend_function_entry {

       char *fname;

       void (*handler)(INTERNAL_FUNCTION_PARAMETERS);

       struct _zend_arg_info *arg_info;

       zend_uint num_args;

       zend_uint flags;

} zend_function_entry;

 

typedef struct _zend_arg_info {

       char *name;

       zend_uint name_len;

       char *class_name;

       zend_uint class_name_len;

       zend_bool array_type_hint;

       zend_bool allow_null;

       zend_bool pass_by_reference;

       zend_bool return_reference;

       int required_num_args;

} zend_arg_info;

typedef struct _zend_fcall_info {

       size_t size;

       HashTable *function_table;

       zval *function_name;

       HashTable *symbol_table;

       zval **retval_ptr_ptr;

       zend_uint param_count;

       zval ***params;

       zval **object_pp;

       zend_bool no_separation;

} zend_fcall_info;

PHP动态运行分析

内存管理

Php使用自己的内存管理代码,使用的内存在php全局堆heap中分配,当前内存不够时,发布内存不够安全错误,内存以块形式存在,可设置内存相关环境变量ZEND_MM_SEG_SIZE和ZEND_MM_COMPACT,先搜索最大内存块,分配内存,否则查找合适的BUCKET,如果没有合适内存块,扩大内存段,如果内存超限,发布内存不够安全错误。释放内存时,将内存块加入free内存链接池,并进行内存块归并。可以检查内存全局堆是否有泄漏。

struct _zend_mm_heap {

       int                 use_zend_alloc;

       size_t              free_bitmap;

       size_t              large_free_bitmap;

       size_t              block_size;

       size_t              compact_size;

       zend_mm_segment    *segments_list;

       zend_mm_storage    *storage;

       size_t              real_size;

       size_t              real_peak;

       size_t              limit;

       size_t              size;

       size_t              peak;

       size_t              reserve_size;

       void               *reserve;

       int                 overflow;

       int                 internal;

       zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2];

       zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS];

       zend_mm_free_block *rest_buckets[2];

};

系统运行

接受apche的请求,request初始化,初始化输出缓冲,找到入口文件,

初始化执行环境,

编译文件,

运行编译结果,可在zend虚拟机中运行。

释放执行环境。

Flex 词法分析,Bison 语法分析。

初始化执行环境

开启内存管理,

开启扩展模块机制,

设置辅助函数,

初始化error表,

初始化栈帧stock frame,

初始化符号cache表、函数表、类表,

置入参数栈,

初始化符号表,

初始化全局变量GLOBALS,

初始化模块列表,

初始化包含文件表include files,

初始化对象池,

初始化持久资源列表,

初始化全局常量,

设置内部函数,

初始化ticks_count,用户错误处理句柄,异常exception,超时timed_out,等。

释放执行环境

关闭超时函数,

释放持久资源列表,

释放全局常量,

模块列表模块消活deactive,

符号表symbol_table析构,

取消用户错误处理句柄、用户错误处理句柄,

清除函数、类的静态变量、参数栈、操作数组、符号cache表,

对象池析构,

释放资源列表,

清除包含文件表include files,

清除栈帧stock frame。

运行超时

如果设置运行超时,

Windows版本启动超时创建线程,创建线程创建超时窗口、事件处理函数,设置定时器。可以设置新的定时器Timer,或者取消定时器。

其它系统直接设置定时器。可以设置新的定时,或者取消定时。

变量转换cast

to int:NULL->0,double->int,string->int,array->不空1 or 0,bool->true 1 or 0,resource->句柄值,object->如可转换,转换,or如兼容,不空1 or 0,default->0。

to double:NULL->0.0,其它如上。

to null:object->如果可转换,转换。其它,释放变量,设置类型为NULL。

to boolean:null->false,其它转换为int的值不为0,true;or false。

to string:null->空字符串,int、double->相应的字符串,bool->true,为“1”,or空字符串,resource->“Resource id [句柄数字]”; array-> "Array",;object->如可转换,转换__tostring,or "Object"。

to array:NULL->空数组;object->属性property转换为数组;其它,成为数组的第一个成员。

to object::NULL->空对象;array->数值值转换为property;其它,成为对象的一个名为scalar成员。

你可能感兴趣的:(数据结构,PHP,Flex,REST,Zend)