$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
returnが返されるのはなぜですか?false
"d"
これは間違いなく設計によるものであり、PHPのドキュメントをくまなく調べましたが、配列の終わりを超えてポインタを無効にすると、PHPソースコードnext
を使用できなくなるという事実への言及は見つかりません。 prev
(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
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));
リチューナー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を取得します。