php7扩展开中的hash遍历

29 篇文章 0 订阅

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值