设为首页 收藏本站
查看: 678|回复: 0

[经验分享] php内核简析

[复制链接]

尚未签到

发表于 2017-3-27 09:39:22 | 显示全部楼层 |阅读模式
变量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成员。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-355932-1-1.html 上篇帖子: php对数组排序 下篇帖子: PHP字符函数大全
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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