2012-05-22 11 views
5
$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

+0

ich vermute einmal bist du das Ende des Feldes weg pat, zurück wird nicht mehr funktionieren.. Nicht sicher, obwohl. – Corbin

+0

@Corbin Ich nehme an, du hast Recht, obwohl die PHP-Entwickler nicht überrascht haben, dass das in der Dokumentation erwähnt wird ... – Alnitak

Antwort

4

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)

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)); 

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

+0

Ich denke, das OP erkennt, dass die wirkliche Frage ist, warum man 'prev' nachher nicht benutzen kann next "erreicht das Ende des Arrays. –

+0

Ich habe erklärt, warum er falschen Wert bekommt –

Verwandte Themen