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

相關文章
相關標籤/搜索