1、zend_hash_num_elements 获取数组元素个数。宏定义如下:
1 #define zend_hash_num_elements(ht) 2 (ht)->nNumOfElements
2、ZEND_HASH_FOREACH_KEY_VAL 遍历数组键值。使用方法:
1 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { 2 // code 3 } ZEND_HASH_FOREACH_END();
ZEND_HASH_FOREACH_KEY_VAL是个宏函数:
1 #define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) 2 ZEND_HASH_FOREACH(ht, 0); 3 _h = _p->h; 4 _key = _p->key; 5 _val = _z;
继续展开 ZEND_HASH_FOREACH:
1 #define ZEND_HASH_FOREACH(_ht, indirect) do { 2 Bucket *_p = (_ht)->arData; 3 Bucket *_end = _p + (_ht)->nNumUsed; 4 for (; _p != _end; _p++) { 5 zval *_z = &_p->val; 6 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { 7 _z = Z_INDIRECT_P(_z); 8 } 9 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
ZEND_HASH_FOREACH_END展开:
1 #define ZEND_HASH_FOREACH_END() 2 } 3 } while (0)
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) {
// code
} ZEND_HASH_FOREACH_END();
完全展开:
1 do { 2 Bucket *_p = (_ht)->arData; // Z_ARRVAL_P(array) ---> ht ---> _ht 3 Bucket *_end = _p + (_ht)->nNumUsed; // 起始地址+偏移地址 4 for (; _p != _end; _p++) { 5 zval *_z = &_p->val; 6 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { 7 _z = Z_INDIRECT_P(_z); 8 } 9 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue; 10 _h = _p->h; // zend_ulong num_key ---> _h 11 _key = _p->key; // zend_string *string_key ---> _key 12 _val = _z; // zval *entry ---> _val 13 { 14 //code 15 } 16 } 17 } while (0)