热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php7扩展开中的hash遍历

PHP7已经发布半年有余了,其扩展开发方法相较PHP5相差很大,这里简单的介绍一下php7中如何遍历hash先来看一下php5中如何遍历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);//重置pos_value使其指向开始部分

	while (zend_hash_get_current_data(write_errors, (void **)&error)/*获取“值”*/
 == 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);//移动指针

	}


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

推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
author-avatar
凯蜜斯特
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有