$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
Dlaczego var_dump
powrót false
zamiast "d"
?php wskaźnik tablicy kuriozum
$a=array('a','b','c','d');
while(key($a)!==NULL){
echo key($a).'=>'.current($a).'<br/>';
next ($a);
}
prev($a);
var_dump(current($a));
Dlaczego var_dump
powrót false
zamiast "d"
?php wskaźnik tablicy kuriozum
To zdecydowanie za projekt, a choć ja czesane przez PHP dokumentacja, nie mogę znaleźć odniesienia do faktu, że po unieważnieniu wskaźnika za pomocą po końcu tablicy nie można już używać prev
, kod źródłowy PHP (zend_hash.c
) wyjaśnia, co się dzieje:
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;
}
Jak widać, zend_hash_move_backwards_ex
(który w PHP, są odwzorowywane na prev
) testy czy obecny wskaźnik jest ważny zanim cokolwiek, a zend_hash_move_forward_ex
ustawi wartość pListNext
który zamierza być null
w przypadku ostatniego elementu.
tj przeciwieństwie można się spodziewać, next
i prev
nie tylko ślepo zwiększyć lub zmniejszyć wskaźnik C następnie sprawdzić wynik zwraca wartość lub NULL, faktycznie sprawdzić wskaźnik przed inkrementacji lub zmniejszanie.
To jest zdecydowanie wadliwa dokumentacja i na pewno musi być udokumentowana. Jak wspomniano w innej odpowiedzi, możesz użyć end
, aby przejść do ostatniego elementu po unieważnieniu wskaźnika przez zapętlenie na liście.
Jednak powinieneś być w stanie zaimplementować odpowiednią logikę (bez konieczności używania end()
) przez klonowanie wskaźnika przed każdym postępem, a następnie użycie sklonowanego wskaźnika po dotarciu do końca tablicy. (ale nie ma naprawdę dobrego powodu, aby to zrobić, jeśli wiesz już, że prev()
jest zepsute przez projekt pod względem nawigacji wstecz już przetestowanej tablicy)
(Poza tematem: Cieszę się, że mogę zobaczyć szanowaną tradycję PHP korzystania inconsistentfunction names żyje i ma się dobrze nawet w bazowego kodu 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));
w tym kodzie obok wrócić następną wartość i przejść do następnego punktu i na koniec pętli daje ostatni element, ale wskaźnik przejścia do następnego tj null. dzięki czemu var_dump(current($a));
retunrs false
ale
$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));
będzie uzyskać pożądany pierwiastek D, gdyż wskazuje na ostatnim elemencie d
Myślę, że OP zdaje sobie z tego sprawę, prawdziwym pytaniem jest dlaczego nie możesz użyć 'prev' po' next' osiąga koniec tablicy. –
Wyjaśniłem, dlaczego otrzymuje fałszywą wartość –
Zgaduję kiedyś odejdziesz pat koniec tablicy prev nie będzie już działać.. Nie jestem tego pewien. – Corbin
@Corbin Oczekuję, że masz rację, chociaż nie jest to zaskakujące, że twórcy PHP nie wspomnieli o tym w dokumentacji ... – Alnitak