PHP 源码 — is_array 函数源码分析

栏目: PHP · 发布时间: 5年前

内容简介:list_destructors 是一个全局静态 HashTable,资源类型注册时,将一个 zval 结构体变量 zv 存放入 list_destructors 的 arData 中,而 zv 的 value.ptr 却指向了 zend_rsrc_list_dtors_entry *lde ,lde中包含的该种资源释放函数指针、持久资源的释放函数指针,资源类型名称,该资源在 hashtable 中的索引依据 (resource_id)等。 --来源于“
  • \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) {

延伸资源类型

const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
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 源码 — is_array 函数源码分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Just My Type

Just My Type

Simon Garfield / Profile Books / 2010-10-21 / GBP 14.99

What's your type? Suddenly everyone's obsessed with fonts. Whether you're enraged by Ikea's Verdanagate, want to know what the Beach Boys have in common with easy Jet or why it's okay to like Comic Sa......一起来看看 《Just My Type》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具