php内置函数分析之current()、next()、prev()、reset()、end()
阅读原文时间:2023年07月11日阅读:3

current()初始指向插入到数组中的第一个单元
next() 将数组的内部指针向前移动一位
prev() 将数组的内部指针倒回一位
reset() 将数组的内部指针指向第一个单元
end() 将数组的内部指针指向最后一个单元

current():

PHP_FUNCTION(current)
{
HashTable *array;
zval *entry;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT(array)
ZEND_PARSE_PARAMETERS_END();
#endif
// 获取内部指针指向的当前单元
if ((entry = zend_hash_get_current_data(array)) == NULL) {
RETURN_FALSE;
}

 if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {  
     entry = Z\_INDIRECT\_P(entry);  
 }

 ZVAL\_DEREF(entry);  
 ZVAL\_COPY(return\_value, entry);  

}

#define zend_hash_get_current_data(ht) \
zend_hash_get_current_data_ex(ht, &(ht)->nInternalPointer)

ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;
Bucket *p;

 IS\_CONSISTENT(ht);  
 if (idx != HT\_INVALID\_IDX) {  
     p = ht->arData + idx; // 数组首地址加偏移量  
     return &p->val;  
 } else {  
     return NULL;  
 }  

}

next():

PHP_FUNCTION(next)
{
HashTable *array;
zval *entry;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif

 // 向前移动指针  
 zend\_hash\_move\_forward(array);

 if (USED\_RET()) {  
     // 获取指针指向的单元  
     if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {  
         RETURN\_FALSE;  
     }

     if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {  
         entry = Z\_INDIRECT\_P(entry);  
     }

     ZVAL\_DEREF(entry);  
     ZVAL\_COPY(return\_value, entry);  
 }  

}

#define zend_hash_move_forward(ht) \
zend_hash_move_forward_ex(ht, &(ht)->nInternalPointer)

ZEND_API int ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;

 IS\_CONSISTENT(ht);  
 HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );

 if (idx != HT\_INVALID\_IDX) {  
     while () {  
         idx++;  
         if (idx >= ht->nNumUsed) { // 内部指针超出单元列表的末端(idx从0开始)  
             \*pos = HT\_INVALID\_IDX; // 保存内部指针为HT\_INVALID\_IDX  
             return SUCCESS;  
         }  
         if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) { // 内部指针向前移动后,指向的是有效元素  
             \*pos = idx; // 保存内部指针  
             return SUCCESS;  
         }  
     }  
 } else {  
      return FAILURE;  
 }  

}

prev():

PHP_FUNCTION(prev)
{
HashTable *array;
zval *entry;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 内部指针倒回一位
zend_hash_move_backwards(array);

 if (USED\_RET()) {  
     // 获取当前指针指向的单元  
     if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {  
         RETURN\_FALSE;  
     }

     if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {  
         entry = Z\_INDIRECT\_P(entry);  
     }

     ZVAL\_DEREF(entry);  
     ZVAL\_COPY(return\_value, entry);  
 }  

}

#define zend_hash_move_backwards(ht) \
zend_hash_move_backwards_ex(ht, &(ht)->nInternalPointer)

ZEND_API int ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx = *pos;

 IS\_CONSISTENT(ht);  
 HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );

 if (idx != HT\_INVALID\_IDX) {  
     while (idx > ) {  
         idx--;  
         if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) { // 内部指针指向的单元有效  
             \*pos = idx;  
             return SUCCESS;  
         }  
     }  
     // 指针倒回一位后没有找到有效的单元  
     \*pos = HT\_INVALID\_IDX;  
      return SUCCESS;  
 } else {  
      return FAILURE;  
 }  

}

reset():

PHP_FUNCTION(reset)
{
HashTable *array;
zval *entry;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif

 // 将内部指针指向第一个单元  
 zend\_hash\_internal\_pointer\_reset(array);

 if (USED\_RET()) {  
     if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {  
         RETURN\_FALSE;  
     }

     if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {  
         entry = Z\_INDIRECT\_P(entry);  
     }

     ZVAL\_DEREF(entry);  
     ZVAL\_COPY(return\_value, entry);  
 }  

}

#define zend_hash_internal_pointer_reset(ht) \
zend_hash_internal_pointer_reset_ex(ht, &(ht)->nInternalPointer)

ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx;

 IS\_CONSISTENT(ht);  
 HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );

 // 内部指针指向数组的一个第一个有效单元  
 for (idx = ; idx < ht->nNumUsed; idx++) {  
     if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) {  
         \*pos = idx;  
         return;  
     }  
 }  
 \*pos = HT\_INVALID\_IDX;  

}

end():

PHP_FUNCTION(end)
{
HashTable *array;
zval *entry;

#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) {
return;
}
#else
ZEND_PARSE_PARAMETERS_START(, )
Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, , )
ZEND_PARSE_PARAMETERS_END();
#endif
// 将数组的内部指针指向最后一个单元
zend_hash_internal_pointer_end(array);

 if (USED\_RET()) {  
     if ((entry = zend\_hash\_get\_current\_data(array)) == NULL) {  
         RETURN\_FALSE;  
     }

     if (Z\_TYPE\_P(entry) == IS\_INDIRECT) {  
         entry = Z\_INDIRECT\_P(entry);  
     }

     ZVAL\_DEREF(entry);  
     ZVAL\_COPY(return\_value, entry);  
 }  

}

#define zend_hash_internal_pointer_end(ht) \
zend_hash_internal_pointer_end_ex(ht, &(ht)->nInternalPointer)

ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
{
uint32_t idx;

 IS\_CONSISTENT(ht);  
 HT\_ASSERT(&ht->nInternalPointer != pos || GC\_REFCOUNT(ht) == );

 // idx从最后一个Bucket开始,第一个出现的有效单元就是数组的末元素  
 idx = ht->nNumUsed;  
 while (idx > ) {  
     idx--;  
     if (Z\_TYPE(ht->arData\[idx\].val) != IS\_UNDEF) {  
         \*pos = idx;  
         return;  
     }  
 }  
 \*pos = HT\_INVALID\_IDX;  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章