繁体   English   中英

php数组指针奇怪

[英]php array pointer oddity

$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 ,如果是最后一个,则该值pListNext null元件。

即不像你想象的那样, nextprev不只是盲目地递增或递减C指针然后检查结果以返回值或NULL,它们实际上在递增或递减之前检查指针。

绝对是文档中的一个缺陷,当然需要记录下来。 正如在另一个回复中提到的,你可以通过循环遍历列表,在指针失效后使用end转到最后一个元素。

但是,您应该能够实现所需的逻辑(无需使用end() ),方法是在每次进程之前克隆指针,然后在到达数组末尾后使用克隆指针。 (但是如果你已经知道prev()在已经迭代的数组的向后导航方面被设计破坏了,那么没有什么理由可以做到这一点)

(偏离主题:我很高兴看到使用不一致的 函数名称的 PHP传统仍然存在,甚至在底层的C代码中也是如此: zend_hash_move_forward_ex vs 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));

在此代码中,接下来返回下一个值并前进到下一个点,在循环结束时,它给出最后一个元素,但指针前进到下一个,即null。 所以你的var_dump(current($a)); retunrs 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,因为它指向最后一个元素d

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM