Resource value
Z_ARRVAL( ) Z_OBJ( ) Z_OBJPROP( ) Z_OBJCE( ) Z_RESVAL( )
Z_ARRVAL_P( ) Z_OBJ_P( ) Z_OBJPROP_P( ) Z_OBJCE_P( ) Z_RESVAL_P( )
Z_ARRVAL_PP( ) Z_OBJ_PP( ) Z_OBJPROP_PP( ) Z_OBJCE_PP( ) Z_RESVAL_PP( )
rot13函数的实现
PHP_FUNCTION(rot13) { zval **arg; char *ch, cap; int i; if (ZEND_NUM_ARGS( ) != 1 || zend_get_parameters_ex(1, &arg) == FAILURE) { WRONG_PARAM_COUNT; } *return_value = **arg; zval_copy_ctor(return_value); convert_to_string(return_value); for(i=0, ch=return_value->value.str.val; i<return_value->value.str.len; i++, ch++) { cap = *ch & 32; *ch &= ~cap; *ch = ((*ch>='A') && (*ch<='Z') ? ((*ch-'A'+13) % 26 + 'A') : *ch) | cap; } }
要获取变量的值,也应该使用Zend定义的宏进行访问。对于简单的标量数据类型、Boolean,long,double, 使用Z_BVAL, Z_LVAL, Z_DVAL
void display_values(zval boolzv, zval *longpzv, zval **doubleppzv) { if (Z_TYPE(boolzv) == IS_BOOL) { php_printf("The value of the boolean is : %s\n", Z_BVAL(boolzv) ? "true" : "false"); } if(Z_TYPE_P(longpzv) == IS_LONG) { php_printf("The value of the long is: %ld\n", Z_LVAL_P(longpzv)); } if(Z_TYPE_PP(doubleppzv) == IS_DOUBLE) { php_printf("The value of the double is : %f\n", Z_DVAL_PP(doubleppzv)); } }
对于字符串类型,因为它含有两个字段char * (Z_STRVAL) 和 int (Z_STRLEN),因此需要用两个宏来进行取值,因为需要二进制安全的输出这个字符串
void display_string(zval *zstr) { if (Z_TYPE_P(zstr) != IS_STRING) { php_printf("The wronng datatype was passed!\n"); return ; } PHPWRITE(Z_STRVAL_P(zstr), Z_STRLEN_P(zstr)); }
因为数组在zval中是以HashTable形式存在的,因此使用Z_ARRVAL()进行访问
void display_zval(zval *value) { switch (Z_TYPE_P(value)) { case IS_NULL: /* 如果是NULL,则不输出任何东西 */ break; case IS_BOOL: /* 如果是bool类型,并且true,则输出1,否则什么也不干 */ if (Z_BVAL_P(value)) { php_printf("1"); } break; case IS_LONG: /* 如果是long整型,则输出数字形式 */ php_printf("%ld", Z_LVAL_P(value)); break; case IS_DOUBLE: /* 如果是double型,则输出浮点数 */ php_printf("%f", Z_DVAL_P(value)); break; case IS_STRING: /* 如果是string型,则二进制安全的输出这个字符串 */ PHPWRITE(Z_STRVAL_P(value), Z_STRLEN_P(value)); break; case IS_RESOURCE: /* 如果是资源,则输出Resource #10 格式的东东 */ php_printf("Resource #%ld", Z_RESVAL_P(value)); break; case IS_ARRAY: /* 如果是Array,则输出Array5个字母! */ php_printf("Array"); break; case IS_OBJECT: php_printf("Object"); break; default: /* Should never happen in practice, * but it's dangerous to make assumptions */ php_printf("Unknown"); break; } }
一些类型转换函数
ZEND_API void convert_to_long(zval *op);
ZEND_API void convert_to_double(zval *op);
ZEND_API void convert_to_null(zval *op);
ZEND_API void convert_to_boolean(zval *op);
ZEND_API void convert_to_array(zval *op);
ZEND_API void convert_to_object(zval *op);
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
6、常量的实例化
我们可以这样实例化
PHP_MINIT_FUNCTION(consts) //模块初始化时定义常量 { REGISTER_LONG_CONSTANT("CONSTS_MEANING_OF_LIFE", 42, CONST_CS | CONST_PERSISTENT); REGISTER_DOUBLE_CONSTANT("CONSTS_PI", 3.1415926, CONST_PERSISTENT); REGISTER_STRING_CONSTANT("CONSTS_NAME", "leon", CONST_CS|CONST_PERSISTENT); } PHP_RINIT_FUNCTION(consts) //每次请求时定义常量 { char buffer[40]; srand((int)time(NULL)); snprintf(buffer, sizeof(buffer), "%d", rand()); REGISTER_STRING_CONSTANT("CONSTS_RAND", estrdup(buffer), CONST_CS); return SUCCESS; }
常见的宏
/*注册LONG类型常量*/
#define REGISTER_LONG_CONSTANT(name, lval, flags) zend_register_long_constant((name), sizeof(name), (lval), (flags), module_number TSRMLS_CC)
/*注册double类型常量*/
#define REGISTER_DOUBLE_CONSTANT(name, dval, flags) zend_register_double_constant((name), sizeof(name), (dval), (flags), module_number TSRMLS_CC)
/*注册STRING类型常量*/
#define REGISTER_STRING_CONSTANT(name, str, flags) zend_register_string_constant((name), sizeof(name), (str), (flags), module_number TSRMLS_CC)