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\n", 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