PHP7内核基础知识之变量类型
2023-09-14 08:57:28 时间
zval结构定义
变量的值
设置变量类型
代码实例
PHP7中是使用zval结构存储变量信息的。zval结构的定义在./Zend/zend_types.h文件中定义。
struct _zval_struct { zend_value value; /* value */ union { struct { ZEND_ENDIAN_LOHI_4( zend_uchar type, /* active type */ zend_uchar type_flags, zend_uchar const_flags, zend_uchar reserved) /* call info for EX(This) */ } v; uint32_t type_info; } u1; union { uint32_t var_flags; uint32_t next; /* hash collision chain */ uint32_t cache_slot; /* literal cache slot */ uint32_t lineno; /* line number (for ast nodes) */ uint32_t num_args; /* arguments number for EX(This) */ uint32_t fe_pos; /* foreach position */ uint32_t fe_iter_idx; /* foreach iterator index */ } u2; };
变量的值
通过上面的代码我们可以看到。变量是通过一个_zval_struct结构体方式存储的。其中结构体中的value存储的是变量的值。这个成员是zend_value类型的。zend_value类型的定义如下:
typedef union _zend_value { zend_long lval; /* long value */ double dval; /* double value */ zend_refcounted *counted; zend_string *str; zend_array *arr; zend_object *obj; zend_resource *res; zend_reference *ref; zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { uint32_t w1; uint32_t w2; } ww; } zend_value;
zend_value是一个联合体。对于小于64位的简单类型,会直接存储值。如,long double。而对于其他比较复杂的类型,如字符串,数组,对象等,是存储的指针。这样,对于简单类型来说,变得简单高效。
获取变量类型zval联合体的type存储的是变量的类型。PHP7已经提供了我们获取变量类型的宏方法Z_TYPE。宏方法的定义如下:
static zend_always_inline zend_uchar zval_get_type(const zval* pz) { return pz- u1.v.type; #define Z_TYPE(zval) zval_get_type( (zval)) #define Z_TYPE_P(zval_p) Z_TYPE(*(zval_p))
设置变量类型
在PHP7中,设置变量类型提供了新的方法。
#define Z_TYPE_INFO(zval) (zval).u1.type_info #define Z_TYPE_INFO_P(zval_p) Z_TYPE_INFO(*(zval_p))
代码实例
下面的代码实现了一个类似var_dump的方法。
PHP_FUNCTION(dump) zval *arg; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", arg) == FAILURE) { return; switch (Z_TYPE_P(arg)) { case IS_NULL: RETVAL_STRING("NULL"); break; case IS_TRUE: RETVAL_STRING("true"); break; case IS_FALSE: RETVAL_STRING("false"); break; case IS_LONG: RETVAL_STRING("integer"); break; case IS_DOUBLE: RETVAL_STRING("double"); break; case IS_STRING: RETVAL_STRING("string"); break; case IS_ARRAY: RETVAL_STRING("array"); break; case IS_OBJECT: RETVAL_STRING("object"); break; case IS_RESOURCE: RETVAL_STRING("resource"); break; default: RETVAL_STRING("unknown type");
相关文章
- linux驱动开发--内核空间中内存的申请与释放
- 解密jQuery内核 DOM操作的核心函数domManip
- [watchdog]内核失败的重启方案
- [Linux内核]软中断与硬中断
- 用户栈和内核栈
- Qt开源作品1-视频流播放ffmpeg内核
- Linux内核 下载外网资源 如何高速下载国外资源 快速下载Linux内核
- 【Linux 内核 内存管理】分区伙伴分配器 ④ ( 备用内存区域列表排序方式 | 节点优先顺序 | 区域优先顺序 | 排序方式优缺点 | 默认排序方式 )
- 【Linux 内核 内存管理】内存管理架构 ② ( 用户空间内存管理 | malloc | ptmalloc | 内核空间内存管理 | sys_brk | sys_mmap | sys_munmap)
- 【Linux 内核】宏内核与微内核架构 ( 操作系统需要满足的要素 | 宏内核 | 微内核 | Linux 内核动态加载机制 )
- linux内核数据包转发流程(二):中断
- 学习笔记 | Linux内核精讲
- Ubuntu下通过源码编译方式升级内核2(基于4.15版本)
- Linux dmesg 命令 - 打印内核环形缓冲区
- Tomcat 内核如何阻塞与唤醒进程?