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

¿Por qué var_dump retorno false en lugar de "d"?php puntero de la lista rareza

+0

supongo pat una vez que has ido al final de la matriz, anterior ya no funcionará.. Aunque no estoy seguro – Corbin

+0

@ Corbin Espero que tengas razón, aunque como era de esperar los desarrolladores de PHP no se han dignado a mencionar que en la documentación ... – Alnitak

Respuesta

4

Es, definitivamente, por diseño, y aunque he peinado a través del PHP documentación, no puedo encontrar ninguna referencia al hecho de que una vez que invalida el puntero por medio de next pasando el final de la matriz ya no puede usar prev, el código fuente de PHP (zend_hash.c) deja en claro lo que está pasando:

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

Como se puede ver, el zend_hash_move_backwards_ex (que, en PHP, se asigna a prev) comprueba si o no el puntero actual es válido antes de hacer nada, y zend_hash_move_forward_ex se establezca el valor en pListNext que se va a ser null en el caso del último elemento.

es decir, a diferencia era de esperar, next y prev No se limite a ciegas aumentar o disminuir un puntero C a continuación, comprobar el resultado a devolver el valor o NULL, que en realidad comprobar el puntero antes de incrementar o disminuir.

Esto es definitivamente un defecto en la documentación y sin duda debe documentarse. Como se menciona en otra respuesta, puede usar end para ir al último elemento después de que un puntero haya sido invalidado al pasar el cursor sobre la lista.

Sin embargo, debe poder implementar la lógica que desee (sin tener que usar end()) clonando el puntero antes de cada progresión y luego usando el puntero clonado después de llegar al final de la matriz. (pero no hay una buena razón para hacer esto si ya sabes prev() está roto por diseño en términos de navegación hacia atrás de una matriz ya iterada)

(Fuera del tema: me alegra ver la respetada tradición de PHP de utilizar inconsistentfunction names está vivo y bien, incluso en el código subyacente de C: 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)); 

en este código siguiente volver el siguiente valor y avanzar al siguiente punto y al final del bucle que da el último elemento pero avance puntero a la siguiente es decir nulo. por lo que sus var_dump(current($a)); retunrs false

pero

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

obtendrá el elemento d deseada, ya que apunta al último elemento d

+0

Creo que el OP se da cuenta de eso, la verdadera pregunta es por qué no puedes usar 'prev' después de' next' llega al final de la matriz. –

+0

Le he explicado por qué está obteniendo un valor falso –