$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"
?
答案 0 :(得分:4)
这绝对是设计的,虽然我已经梳理了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()
在已经迭代的数组的向后导航方面被设计破坏了,那么没有什么理由可以做到这一点。
(偏离主题:我很高兴看到使用inconsistent function names的受人尊敬的PHP传统仍然存在,即使在基础C代码中也是如此:zend_hash_move_forward_ex
vs {{1 }}。)
答案 1 :(得分:0)
$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
在此代码中接下来返回下一个值并前进到下一个点,在循环结束时,它给出最后一个元素,但指针前进到下一个,即null。所以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));
当你指向最后一个元素d
时,你会得到你想要的元素