六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 46|回复: 0

php内核简析

[复制链接]

升级  30%

3

主题

3

主题

3

主题

童生

Rank: 1

积分
15
 楼主| 发表于 2013-1-25 03:30:31 | 显示全部楼层 |阅读模式
变量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成员。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表