$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
为什么
var_dump
返回false
而不是"d"
?这绝对是有意设计的。虽然我已经查阅了PHP文档,但未找到任何关于当通过next
操作超出数组末尾后,指针变为无效,因此无法再使用prev
的说明。不过,PHP源代码(zend_hash.c
)清楚地解释了其中的原理。
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
{
HashPosition *current = pos ? pos : &ht->pInternalPointer;
IS_CONSISTENT(ht);
if (*current) {
*current = (*current)->pListNext;
return SUCCESS;
} else
return FAILURE;
}
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
{
HashPosition *current = pos ? pos : &ht->pInternalPointer;
IS_CONSISTENT(ht);
if (*current) {
*current = (*current)->pListLast;
return SUCCESS;
} else
return FAILURE;
}
zend_hash_move_backwards_ex
(在PHP中映射为prev
)在执行任何操作之前会测试当前指针是否有效,而zend_hash_move_forward_ex
会将值设置为pListNext
,在最后一个元素的情况下将是null
。next
和prev
并不仅仅是盲目地增加或减少C指针,然后检查结果来返回值或NULL,它们实际上是在增加或减少指针之前先检查指针。end
转到最后一个元素。end()
),方法是在每次进展之前克隆指针,然后在到达数组末尾后使用克隆的指针。(但如果您已经知道prev()
在已迭代数组的向后导航方面存在设计缺陷,那么没有真正好的理由这样做)
(离题:我很高兴看到尊重的PHP传统在底层C代码中使用不一致 函数名称仍然健在: zend_hash_move_forward_ex
与zend_hash_move_backward*s*_ex
。)
$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
var_dump(current($a));
返回false
。$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
//prev($a);
end(($a);
var_dump(current($a));