发布时间:2015-05-27 19:23:11作者:知识屋
typedef int (*apply_func_t)(void *pDest TSRMLS_DC);void zend_hash_apply(HashTable *ht, apply_func_t apply_func TSRMLS_DC);
typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *data TSRMLS_DC);一个是可以传递参数的,还有一个是不传递参数,只传递哈希表中的值的。对于可传递参数的函数而言,在扩展中应用到可能性更大。回调函数可能有不同的返回值:
int php_sample_print_zval(zval **val TSRMLS_DC){ //重新copy一个zval,防止破坏原数据 zval tmpcopy = **val; zval_copy_ctor(&tmpcopy); //转换为字符串 INIT_PZVAL(&tmpcopy); convert_to_string(&tmpcopy); //开始输出 php_printf("The value is: "); PHPWRITE(Z_STRVAL(tmpcopy), Z_STRLEN(tmpcopy)); php_printf("/n"); //毁尸灭迹 zval_dtor(&tmpcopy); //返回,继续遍历下一个~ return ZEND_HASH_APPLY_KEEP;}然后定义循环函数:zend_hash_apply(arrht, php_sample_print_zval TSRMLS_CC);
$val) { echo "The value of $key is: $val/n"; }?>针对这段php代码的c代码:
int php_sample_print_zval_and_key(zval **val, int num_args, va_list args, zend_hash_key *hash_key) { /* 复制zval从而使得原来的内容被保存下来 */ zval tmpcopy = **val; /* tsrm_ls is needed by output functions */ TSRMLS_FETCH(); zval_copy_ctor(&tmpcopy); /* Reset refcount & Convert */ INIT_PZVAL(&tmpcopy); convert_to_string(&tmpcopy); /* 输出 */ php_printf("The value of "); if (hash_key->nKeyLength) { /* 如果是字符串类型的key */ PHPWRITE(hash_key->arKey, hash_key->nKeyLength); } else { /* 如果是数字类型的key */ php_printf("%ld", hash_key->h); } php_printf(" is: "); PHPWRITE(Z_STRVAL(tmpcopy), Z_STRLEN(tmpcopy)); php_printf("/n"); /* Toss out old copy */ zval_dtor(&tmpcopy); /* continue; */ return ZEND_HASH_APPLY_KEEP;}
1, 'b'=>2, 'c'=>3); reset($arr); while (list($key, $val) = each($arr)) { /* Do something with $key and $val */ } reset($arr); $firstkey = key($arr); $firstval = current($arr); $bval = next($arr); $cval = next($arr);?>每一个相应的函数都会有一个zend版本:
* /* reset() */void zend_hash_internal_pointer_reset(HashTable *ht); /* key() */int zend_hash_get_current_key(HashTable *ht, char **strIdx, unit *strIdxLen, ulong *numIdx, zend_bool duplicate); * /* current() */int zend_hash_get_current_data(HashTable *ht, void **pData); * /* next()/each() */int zend_hash_move_forward(HashTable *ht); * /* prev() */int zend_hash_move_backwards(HashTable *ht); * /* end() */void zend_hash_internal_pointer_end(HashTable *ht); * /* Other... */int zend_hash_get_current_key_type(HashTable *ht);int zend_hash_has_more_elements(HashTable *ht);next() prev() end()其实都是找到相应的索引值,再用zend_hash_get_current_data()返回元素值
void php_sample_print_var_hash(HashTable *arrht){ for(zend_hash_internal_pointer_reset(arrht); zend_hash_has_more_elements(arrht) == SUCCESS; zend_hash_move_forward(arrht)) { char *key; uint keylen; ulong idx; int type; zval **ppzval, tmpcopy; type = zend_hash_get_current_key_ex(arrht, &key, &keylen, &idx, 0, NULL);//获得返回的key的类型。这个类型可能有三种 if (zend_hash_get_current_data(arrht, (void**)&ppzval) == FAILURE) {//获得当前索引所指的数据值 /* Should never actually fail * since the key is known to exist. */ continue; } /* 复制zval的值,从而原来的值不会被破坏掉 */ tmpcopy = **ppzval; zval_copy_ctor(&tmpcopy); /* 重新设定refcount 并且转换 */ INIT_PZVAL(&tmpcopy); convert_to_string(&tmpcopy); /* 输出 */ php_printf("The value of "); if (type == HASH_KEY_IS_STRING) { /* String Key / Associative */ PHPWRITE(key, keylen); } else { /* Numeric Key */ php_printf("%ld", idx); } php_printf(" is: "); PHPWRITE(Z_STRVAL(tmpcopy), Z_STRLEN(tmpcopy)); php_printf("/n"); /* 销毁原来的副本 */ zval_dtor(&tmpcopy); }}来看一下zend_hash_get_current_key_ex返回值的可能性:Constant Meaning
int zend_hash_del(HashTable *ht, char *arKey, uint nKeyLen);int zend_hash_index_del(HashTable *ht, ulong h);返回SUCCESS OR FAILURE
int sample_strvec_handler(int argc, char **argv TSRMLS_DC){ HashTable *ht; /* 为哈希表分配空间 */ ALLOC_HASHTABLE(ht); /* 初始化哈希表的内部状态 */ if (zend_hash_init(ht, argc, NULL, ZVAL_PTR_DTOR, 0) == FAILURE) { FREE_HASHTABLE(ht); return FAILURE; } /* 把每个字符串变成zval* */ while (argc) { zval *value; MAKE_STD_ZVAL(value); ZVAL_STRING(value, argv[argc], 1); argv++; if (zend_hash_next_index_insert(ht, (void**)&value, sizeof(zval*)) == FAILURE) { /* 对于分配失败的情况应该跳掉 */ zval_ptr_dtor(&value); } } /* Do some work */ process_hashtable(ht); /* 毁坏哈希表 * 释放所有的分配的空旷 */ zend_hash_destroy(ht); /* Free the HashTable itself */ FREE_HASHTABLE(ht); return SUCCESS;}
int zend_hash_minmax(HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);flag为0就返回最小值,否则就是最大值。
int fname_compare(zend_function *a, zend_function *b TSRMLS_DC){ return strcasecmp(a->common.function_name, b->common.function_name);}void php_sample_funcname_sort(TSRMLS_D){ zend_function *fe; if (zend_hash_minmax(EG(function_table), fname_compare, 0, (void **)&fe) == SUCCESS) { php_printf("Min function: %s/n", fe->common.function_name); } if (zend_hash_minmax(EG(function_table), fname_compare, 1, (void **)&fe) == SUCCESS) { php_printf("Max function: %s/n", fe->common.function_name); }}
typedef void (*sort_func_t)(void **Buckets, size_t numBuckets, size_t sizBucket, compare_func_t comp TSRMLS_DC);int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);一般就用zend_qsort作为sort_func就够了。renumber这个参数如果设为1的话,那么就会抛弃原有的索引键值关系,赋予新的数字键值。zend_hash_sort(target_hash, zend_qsort,array_data_compare, 1 TSRMLS_CC);array_data_compare是一个返回compare_func_t类型数据的函数,它将按照HashTable中zval*值的大小进行排序。
如何对PHP文件进行加密方法 PHP实现加密的几种方式介绍
php生成圆角图片的方法 电脑中php怎么生成圆角图片教程
用PHP构建一个留言本方法步骤 php怎么实现留言板功能
php中三元运算符用法 php中的三元运算符使用说明
php文件如何怎么打开方式介绍 php文件用什么打开方法
PHP怎么插入数据库方法步骤 php编程怎么导入数据库教程
如何安装PHPstorm并配置方法教程 phpstorm安装后要进行哪些配置
PHP 获取远程文件大小的3种解决方法 如何用PHP获取远程大文件的大小
20个实用PHP实例代码 php接口开发实例代码详细介绍
如何架设PHP服务器方法步骤 怎么搭建php服务器简单教程