php7扩展开中的hash遍历
PHP7已经发布半年有余了,其扩展开发方法相较PHP5相差很大,这里简单的介绍一下php7中如何遍历hash
先来看一下php5中如何遍历hash的
-------------------------------------------------------------------------------------------- HashPosition pos_value; const char ** entry_value; zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value);//重置pos_value使其指向开始部分 while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)/*获取“值”*/) { char *s_key; unsigned int s_len; zend_ulong num_key; size_t value_len = strlen(*entry_value); if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, &pos_value)/*获取"键"*/) { ca_payload_len += php_mysqlnd_net_store_length_size(s_len); ca_payload_len += s_len; ca_payload_len += php_mysqlnd_net_store_length_size(value_len); ca_payload_len += value_len; } zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value);//移动指针 } -------------------------------------------------------------------------------------------- HashTable *write_errors = Z_ARRVAL_PP(z_write_errors); zval **error; zend_hash_internal_pointer_reset(write_errors);/<span style="font-family: Arial, Helvetica, sans-serif;">/重置pos_value使其指向开始部分</span> while (zend_hash_get_current_data(write_errors, (void **)&error)<span style="font-family: Arial, Helvetica, sans-serif;">/*获取“值”*/</span> == SUCCESS) { zval *index = NULL, *code = NULL, *errmsg = NULL; if (Z_TYPE_PP(error) != IS_ARRAY) { php_mongo_api_throw_exception_from_server_code(connection, 102, "Got write errors, but don"t know how to parse them", *error TSRMLS_CC); break; } if (zend_hash_find(Z_ARRVAL_PP(error), "index", strlen("index") + 1, (void**)&index) == SUCCESS) { convert_to_long_ex(index); } if (zend_hash_find(Z_ARRVAL_PP(error), "code", strlen("code") + 1, (void**)&code) == SUCCESS) { convert_to_long_ex(code); } if (zend_hash_find(Z_ARRVAL_PP(error), "errmsg", strlen("errmsg") + 1, (void**)&errmsg) == SUCCESS) { convert_to_string_ex(errmsg); } /* FIXME: Do we care about the index? */ php_mongo_api_throw_exception_from_server_code(connection, Z_LVAL_PP(code), Z_STRVAL_PP(errmsg), document TSRMLS_CC); zend_hash_move_forward(write_errors);//<span style="font-family: Arial, Helvetica, sans-serif;">移动指针</span> }
php7中
-------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_NUM_KEY_PTR //取键值对,键为zend_ulong,值为相应的PTR HashTable *table; zend_ulong id = 0L; ZEND_HASH_FOREACH_NUM_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table) { phpdbg_breakbase_t *brake; }ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_STR_KEY //取键,键为zend_string*型 zend_string *file; ZEND_HASH_FOREACH_STR_KEY(&PHPDBG_G(file_sources), file) { HashTable *fileht; phpdbg_debug("Compare against loaded %s ", file); if (!(pending = ((fileht = phpdbg_resolve_pending_file_break_ex(ZSTR_VAL(file), ZSTR_LEN(file), path_str, broken)) == NULL))) { new_break = *(phpdbg_breakfile_t *) zend_hash_index_find_ptr(fileht, line_num); break; } } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_KEY_PTR //取键值对,键为zend_ulong型,zend_string*型,值为相应的PTR HashTable **table, zend_ulong *numkey, zend_string **strkey) /* {{{ */ if ((*table = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id))) { phpdbg_breakbase_t *brake; ZEND_HASH_FOREACH_KEY_PTR(*table, *numkey, *strkey, brake) { if (brake->id == id) { return brake; } } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_NUM_KEY_VAL //使用number key取hash中的“值”,值为zval*型,键为zend_ulong型 zval *trace, *frame, rv; zend_ulong index; trace = zend_read_property(base_ce, object, "trace", sizeof("trace")-1, 1, &rv); if (Z_TYPE_P(trace) != IS_ARRAY) { RETURN_FALSE; } ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) { if (Z_TYPE_P(frame) != IS_ARRAY) { zend_error(E_WARNING, "Expected array for frame %pu", index); continue; } _build_trace_string(&str, Z_ARRVAL_P(frame), num++); } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_NUM_KEY //取hash中的number hash key,键为zend_ulong型 zend_ulong leaf; ZEND_HASH_FOREACH_NUM_KEY(&src->child.ht, leaf) { zend_generator_add_single_child(dest, child, (zend_generator *) leaf); } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_STR_KEY_PTR //取hash中的键值对,键为zend_string*型,值为相关的指针型 zend_property_info *property_info; zend_string *key; ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->properties_info, key, property_info) { do_inherit_property(property_info, key, ce); } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_VAL //直接取hash中的“值”,值为zval*型 zval* arg ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) { if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) { ZVAL_NEW_REF(params, arg); if (Z_REFCOUNTED_P(arg)) { Z_ADDREF_P(arg); } } else { ZVAL_COPY(params, arg); } params++; n++; } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_STR_KEY_VAL //取键值对,键为zend_string*型,值为zval*型 zend_string * key; zval * entry_value; ZEND_HASH_FOREACH_STR_KEY_VAL(packet->connect_attr, key, entry_value) { if (key) { /* HASH_KEY_IS_STRING */ size_t value_len = Z_STRLEN_P(entry_value); ca_payload_len += php_mysqlnd_net_store_length_size(ZSTR_LEN(key)); ca_payload_len += ZSTR_LEN(key); ca_payload_len += php_mysqlnd_net_store_length_size(value_len); ca_payload_len += value_len; } } ZEND_HASH_FOREACH_END(); -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_KEY_VAL //取hash中的键值对,键为zend_string*, zend_ulong型,值为zval*型 if (options) { zval *attr_value; zend_ulong long_key; zend_string *str_key = NULL; ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), long_key, str_key, attr_value) { if (str_key) { continue; } pdo_dbh_attribute_set(dbh, long_key, attr_value); } ZEND_HASH_FOREACH_END(); } -------------------------------------------------------------------------------------------- //ZEND_HASH_FOREACH_PTR //直接取hash中存的“值”,值为任意相应指针类型 pdo_driver_t *pdriver; if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); ZEND_HASH_FOREACH_PTR(&pdo_driver_hash, pdriver) { add_next_index_stringl(return_value, (char*)pdriver->driver_name, pdriver->driver_name_len); } ZEND_HASH_FOREACH_END();
由以上不能看出这些ZEND_HASH_FOREACH_*存在的规律。 这些宏的出现可以让我们更简单的遍历hash
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: PHP扩展程序中返回数组对象
- 下一篇: PHP源码之数组的内部实现