做网站的书知乎,公司做的网站过期了,上海企业所得税怎么征收,中小企业网络设计与实现php 中的 is_arrayphp 中的 is_array#xff0c;它的签名是 is_array ( mixed $var ) : bool实现的源码在\ext\standard\type.c中可以找到PHP_FUNCTION(is_array)所处的位置#xff0c;大概位于 273 行。在 PHP 中#xff0c;这个系列的函数#xff0c;是由很多个#xff…php 中的 is_arrayphp 中的 is_array它的签名是 is_array ( mixed $var ) : bool实现的源码在\ext\standard\type.c中可以找到PHP_FUNCTION(is_array)所处的位置大概位于 273 行。在 PHP 中这个系列的函数是由很多个除了它本身之外还有 is_bool 、 is_countable 、 is_callback 、 is_int 、 is_object 、 is_string 等等在它们之中大部分的源代码也都是和 is_array 的类似PHP_FUNCTION(is_array){php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);}它的定义很简洁直接调用了php_is_type宏INTERNAL_FUNCTION_PARAM_PASSTHRU的作用是将调用 is_array 时的参数原样传递给 php_is_type 。它的定义如下#define INTERNAL_FUNCTION_PARAM_PASSTHRU execute_data, return_value函数 php_is_type 的定义如下static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type){zval *arg;ZEND_PARSE_PARAMETERS_START(1, 1)Z_PARAM_ZVAL(arg)ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);if (Z_TYPE_P(arg) type) {if (type IS_RESOURCE) {const char *type_name zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));if (!type_name) {RETURN_FALSE;}}RETURN_TRUE;} else {RETURN_FALSE;}}前面几行是参数解析部分ZEND_PARSE_PARAMETERS_START(1, 1)Z_PARAM_ZVAL(arg)ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);随后通过Z_TYPE_P(arg)获取变量的类型再让其结果和IS_ARRAY判等。如果为真则表示变量是数组否则不是。Z_TYPE_P 的作用很明显就是获取变量的类型这个宏展开后如下static zend_always_inline zend_uchar zval_get_type(const zval* pz) {return pz-u1.v.type;}其中的 pz 就是 zval 指针 zval 就是 经常提到的_zval_struct:struct _zval_struct {zend_value value;/* 值 */union {struct {ZEND_ENDIAN_LOHI_3(zend_uchar type,/* 类型 */zend_uchar type_flags,union {uint16_t call_info; /* call info for EX(This) */uint16_t extra; /* not further specified */} u)} v;uint32_t type_info;} u1;union {uint32_t next; /* hash 碰撞时用到的链表 */uint32_t cache_slot; /* cache slot (for RECV_INIT) */uint32_t opline_num; /* opline number (for FAST_CALL) */uint32_t lineno; /* 行号 (ast 节点中) */uint32_t num_args; /* 参数数量 for EX(This) */uint32_t fe_pos; /* foreach 时的所在位置 */uint32_t fe_iter_idx; /* foreach iterator index */uint32_t access_flags; /* 类时的访问权限标志位 */uint32_t property_guard; /* single property guard */uint32_t constant_flags; /* constant flags */uint32_t extra; /* 保留字段 */} u2;};不做深入介绍了。接续看php_is_type在判断类型时有个地方比较蹊跷if (type IS_RESOURCE) {为何这里要判断是否是资源类型延伸资源类型这里延伸一下如果用 php_is_type 判断的是资源类型这里会调用const char *type_name zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));其中有 zend_rsrc_list_get_rsrc_type 的调用其实现如下const char *zend_rsrc_list_get_rsrc_type(zend_resource *res){zend_rsrc_list_dtors_entry *lde;lde zend_hash_index_find_ptr(list_destructors, res-type);if (lde) {return lde-type_name;} else {return NULL;}}有一个叫做list_destructors的静态变量它的作用如下list_destructors 是一个全局静态 HashTable资源类型注册时将一个 zval 结构体变量 zv 存放入 list_destructors 的 arData 中而 zv 的 value.ptr 却指向了 zend_rsrc_list_dtors_entry *lde lde中包含的该种资源释放函数指针、持久资源的释放函数指针资源类型名称该资源在 hashtable 中的索引依据 (resource_id)等。 --来源于“PHP7 使用资源包裹第三方扩展原理分析”也就是说创建了一个资源类型R1时就会向 list_destructors 中存入一份 zend_rsrc_list_dtors_entry其中包含了该资源R1的一些信息这里的zend_hash_index_find_ptr就是找到资源对应的zend_rsrc_list_dtors_entry从而取其中的lde-type_name如果 type 成员是存在的则说明是资源类型。总结PHP 中使用is_*系列判断类型的函数大部分都是通过变量底层 zval 中的u1.v.type来判断类型值如果是资源类型需要通过 list_destructors 查询对应的资源类型是否存在如果存在说明资源句柄是可以正常使用的。更多PHP相关技术文章请访问PHP教程栏目进行学习