PHP扩展开发教程(总结)(3)

struct _zend_execution_globals { ... HashTable symbol_table; /* 全局作用域,如果没有进入函数内部,全局=活动 */ HashTable *active_symbol_table; /* 活动作用域,当前作用域 */ ... }

通常,使用EG(symbol_table)获取的是全局作用域中的符号表,使用EG(active_symbol_table)获取的是当前作用域下的符号表

例如 来定义$foo = 'bar'

zval *fooval;
 
MAKE_STD_ZVAL(fooval);
ZVAL_STRING(fooval, "bar", 1);
ZEND_SET_SYMBOL(EG(active_symbol_table), "foo", fooval);

或者从符号表中查找$foo

zval **fooval;
if(zend_hash_find(&EG(symbol_table), "foo", sizeof("foo"), (void **)&fooval) == SUCCESS) {
    RETURN_STRINGL(Z_STRVAL_PP(fooval), Z_STRLEN_PP(fooval));
} else {
    RETURN_FALSE;
}

上面的代码中,EG(active_symbol_table) == &EG(symbol_table)

3、CG() 用来访问核心全局变量。(zend/zend_globals_macros.h)

4、PG() PHP全局变量。我们知道php.ini会映射一个或者多个PHP全局结构。(main/php_globals.h)

5、FG() 文件全局变量。大多数文件I/O或相关的全局变量的数据流都塞进标准扩展出口结构。(ext/standard/file.h)

5、获取变量的类型和值

#define Z_TYPE(zval)        (zval).type
#define Z_TYPE_P(zval_p)    Z_TYPE(*zval_p)
#define Z_TYPE_PP(zval_pp)  Z_TYPE(**zval_pp)

比如获取一个变量的类型

void describe_zval(zval *foo) { if ( Z_TYPE_P(foo) == IS_NULL ) { php_printf("这个变量的数据类型是: NULL"); } else { php_printf("这个变量的数据类型不是NULL,这种数据类型对应的数字是: %d", Z_TYPE_P(foo)); } }

有这么几种类型

#define IS_NULL     0
#define IS_LONG     1
#define IS_DOUBLE   2
#define IS_BOOL     3
#define IS_ARRAY    4
#define IS_OBJECT   5
#define IS_STRING   6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY   9
#define IS_CALLABLE 10

php_printf()函数是内核对printf()函数的一层封装,我们可以像使用printf()函数那样使用它,以一个P结尾的宏的参数大多是*zval型变量。 此外获取变量类型的宏还有两个,分别是Z_TYPE和Z_TYPE_PP,前者的参数是zval型,而后者的参数则是**zval

比如gettype函数的实现

//开始定义php语言中的函数gettype PHP_FUNCTION(gettype) { //arg间接指向调用gettype函数时所传递的参数。是一个zval**结构 //所以我们要对他使用__PP后缀的宏。 zval **arg; //这个if的操作主要是让arg指向参数~ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) { return; } //调用Z_TYPE_PP宏来获取arg指向zval的类型。 //然后是一个switch结构,RETVAL_STRING宏代表这gettype函数返回的字符串类型的值 switch (Z_TYPE_PP(arg)) { case IS_NULL: RETVAL_STRING("NULL", 1); break; case IS_BOOL: RETVAL_STRING("boolean", 1); break; case IS_LONG: RETVAL_STRING("integer", 1); break; case IS_DOUBLE: RETVAL_STRING("double", 1); break; case IS_STRING: RETVAL_STRING("string", 1); break; case IS_ARRAY: RETVAL_STRING("array", 1); break; case IS_OBJECT: RETVAL_STRING("object", 1); break; case IS_RESOURCE: { char *type_name; type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC); if (type_name) { RETVAL_STRING("resource", 1); break; } } default: RETVAL_STRING("unknown type", 1); } }

获取变量的值,有这么多宏来获取

Long

Boolean

Double

String value

String length


Z_LVAL( )   Z_BVAL( )   Z_DVAL( )   Z_STRVAL( )   Z_STRLEN( )  
Z_LVAL_P( )   Z_BVAL_P( )   Z_DVAL_P( )   Z_STRVAL_P( )   Z_STRLEN_P( )  
Z_LVAL_PP( )   Z_BVAL_PP( )   Z_DVAL_PP( )   Z_STRVAL_PP( )   Z_STRLEN_PP( )  

HashTable

 

Object

 

Object properties

 

Object class entry

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/0d806cb92c748d14ef3746801d3b4f7c.html