rareza de puntero de matriz php

$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 que var_dump retorno false en lugar de "d" ?

preguntado el 22 de mayo de 12 a las 07:05

Supongo que una vez que te hayas ido al final de la matriz, prev ya no funcionará. Aunque no estoy seguro. -

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

2 Respuestas

Definitivamente es por diseño, y aunque he revisado la documentación de PHP, no puedo encontrar ninguna referencia al hecho de que una vez que invalidas el puntero por medio de nextpasando el final de la matriz que ya no puede usar prev, el código fuente de PHP (zend_hash.c) deja 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, está asignado a prev) comprueba si el puntero actual es válido o no antes de hacer nada, y zend_hash_move_forward_ex establecerá el valor en pListNext que va a ser null en el caso del último elemento.

es decir, a diferencia de lo que cabría esperar, next y prev no solo incremente o disminuya ciegamente un puntero C y luego verifique el resultado para devolver el valor o NULL, en realidad verifican el puntero antes de incrementar o disminuir.

Es que probar definitivamente una falla en la documentación y ciertamente necesita ser documentada. Como se menciona en otra respuesta, puede usar end para ir al último elemento después de que un puntero haya sido invalidado recorriendo la lista.

Sin embargo, debería 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 de tema: me alegra ver la respetada tradición PHP de usar inconsistente nombres de funciones está vivo y bien incluso en el código C subyacente: zend_hash_move_forward_ex vs zend_hash_move_backward*s*_ex.)

Respondido 12 Abr '17, 08:04

$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, a continuación, devuelve el siguiente valor y avanza al siguiente punto y al final del ciclo da el último elemento pero el puntero avanza al siguiente, es decir, nulo. entonces tus var_dump(current($a)); devoluciones 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á su elemento deseado d ya que apunta al último elemento d

contestado el 22 de mayo de 12 a las 08:05

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. - Mahmoud Al-Qudsi

He explicado por qué está obteniendo un valor falso: Rohit Choudhary

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.