要在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