$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
Warum var_dump
Rückkehr false
statt "d"
?PHP-Array-Zeiger Kuriosität
$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
Warum var_dump
Rückkehr false
statt "d"
?PHP-Array-Zeiger Kuriosität
Es ist auf jeden Fall von Design, und obwohl ich durch die PHP gekämmt Dokumentation, kann ich keinen Hinweis darauf finden, dass, sobald Sie den Zeiger mittels next
ing über das Ende des Arrays ungültig machen prev
, der PHP-Quellcode (zend_hash.c
) macht es klar, was los ist:
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;
}
Wie Sie sehen können, die zend_hash_move_backwards_ex
(die in PHP, bis prev
abgebildet wird) prüft, ob oder nicht der aktuelle Zeiger gültig ist, bevor etwas zu tun, und zend_hash_move_forward_ex
den Wert auf pListNext
gesetzt, der wird sei null
im Falle des letzten Elements. D. H. Im Gegensatz zu dem, was Sie erwarten, next
und prev
nicht einfach blind einen C-Zeiger inkrementieren oder dekrementieren, dann das Ergebnis überprüfen, um den Wert zurückzugeben, oder NULL, sie prüfen den Zeiger vor dem Inkrementieren oder Dekrementieren.
Dies ist definitiv ein Fehler in der Dokumentation und muss sicherlich dokumentiert werden. Wie in einer anderen Antwort erwähnt, können Sie end
verwenden, um zum letzten Element zu gehen, nachdem ein Zeiger durch Schleifen der Liste ungültig gemacht wurde.
Sie sollten jedoch in der Lage sein, die gewünschte Logik zu implementieren (ohne end()
zu verwenden), indem Sie den Zeiger vor jeder Progression klonen und dann den geklonten Zeiger verwenden, nachdem Sie das Ende des Arrays erreicht haben. (Aber es gibt keinen wirklich guten Grund, dies zu tun, wenn Sie bereits wissen prev()
ist gebrochen in Bezug auf die Rückwärtsnavigation eines bereits iterierten Array)
(Off-Thema: Ich bin froh, die respektierte PHP-Tradition zu sehen von inconsistent verwendet, ist function names lebendig und gut, auch im zugrundeliegenden C-Code: 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));
in diesem Code neben den nächsten Wert und zum nächsten Punkt zurück, und am Ende der Schleife gibt es das letzte Element, sondern Zeiger weiter zu nächstem dh null. so Ihre var_dump(current($a));
retunrs false
aber
$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));
Sie Ihr gewünschtes Element d erhalten, wie es auf das letzte Element d Punkte
Ich denke, das OP erkennt, dass die wirkliche Frage ist, warum man 'prev' nachher nicht benutzen kann next "erreicht das Ende des Arrays. –
Ich habe erklärt, warum er falschen Wert bekommt –
ich vermute einmal bist du das Ende des Feldes weg pat, zurück wird nicht mehr funktionieren.. Nicht sicher, obwohl. – Corbin
@Corbin Ich nehme an, du hast Recht, obwohl die PHP-Entwickler nicht überrascht haben, dass das in der Dokumentation erwähnt wird ... – Alnitak