php扩展开发-数组处理(一)

要在PHP扩展中处理数组类型参数,首先要了解如下ZEND API:
Z_TYPE_PP() //获取数据类型
zend_hash_internal_pointer_reset_ex();//初始化hash指针
zend_hash_get_current_data_ex() //获取当前hash存储值
zend_hash_move_forward_ex()//hahs指针移动至下一位
zend_hash_get_current_key_ex()//获取当前hash存储索引
array_init()//初始化哈希数组
add_assoc_zval_ex()//添加数组元素 php

如今有一个PHP扩展开发需求,要求开发一个函数,传入数组参数,将数组元素url编码后返回该数组。开发实例以下: linux

1.进入php源码包ext目录,运行命令
#./ext_skel --extname=mytools nginx

2.进入mytools目录
修改config.m4文件,去掉dnl注释
 PHP_ARG_ENABLE(mytools, whether to enable mytools support,
dnl Make sure that the comment is aligned:
[  --enable-mytools           Enable mytools support]) 数组

3.修改php_mytools.h文件
加入PHP_FUNCTION(array_urlencode); 函数


4.修改mytools.c文件 测试

const zend_function_entry mytools_functions[] = {
PHP_FE(confirm_mytools_compiled, NULL)
PHP_FE(array_urlencode, NULL)
        {NULL, NULL, NULL}  /* Must be the last line in class_ext_functions[] */
};


尾部加入
PHP_FUNCTION(array_urlencode)
{
	zval **array_input;
	if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array_input) == FAILURE){
        return;
    }
	
	SEPARATE_ZVAL(array_input);
	if (Z_TYPE_PP(array_input) == IS_ARRAY) {
		char *key;
		uint key_len;
		ulong index;
		HashPosition pos;
		zval **data;

for (
			  zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(array_input), &pos);
			 zend_hash_get_current_data_ex(Z_ARRVAL_PP(array_input), (void **) &data, &pos) == SUCCESS;
			 zend_hash_move_forward_ex(Z_ARRVAL_PP(array_input), &pos)
		) {	

			if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(array_input), &key, &key_len, &index, 0, &pos) != HASH_KEY_IS_STRING) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Numeric keys are not allowed in the definition array");
				zval_dtor(return_value);
				RETURN_FALSE;
	 		}

			
			SEPARATE_ZVAL(data);
			if (Z_TYPE_PP(data) == IS_OBJECT) {
				zend_class_entry *ce;
				ce = Z_OBJCE_PP(data);
				if (!ce->__tostring) {
					ZVAL_FALSE(*data);
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array's value contain object and can not be converted to string ");
					return;
				}
			}

			convert_to_string(*data);

			char *out_str;
			int str_len = strlen(Z_STRVAL_PP(data));
			int out_str_len;

			out_str = php_url_encode((const char*)(Z_STRVAL_PP(data)), str_len, &out_str_len);


			zval *nval;
			ALLOC_ZVAL(nval);
			MAKE_STD_ZVAL(nval);
			ZVAL_STRING(nval, out_str , 1);

			add_assoc_zval_ex(return_value, key, key_len, nval);
		}
	}else{
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter is not array type");
			return;
	}

}

5.编译安装
/www/wdlinux/nginx_php-5.3.17/bin/phpize
./configure --with-php-config=/www/wdlinux/nginx_php-5.3.17/bin/php-config
make
make install ui

6.修改php.ini,,添加扩展
[mytools]
extension_dir=/www/wdlinux/nginx_php-5.3.17/lib/php/extensions/no-debug-non-zts-20090626
extension=mytools.so google


7.重启nginx,测试 编码

<?php
$arr = array('a'=>'http://www.google.com/?s=ssdd&t=32311#', 'b'=>'http://www.baidu.com/?s=ss dd');
var_dump(array_urlencode($arr));


若是您要转载此文章,请注明出处:http://my.oschina.net/u/554660/blog/169491 url

相关文章
相关标签/搜索