check the "array_walk" source code and u will see. array_walk use pos to fetch item, and in every loop, the pos move forward.
do {
/* Retrieve value */
zv = zend_hash_get_current_data_ex(target_hash, &pos);
/* Retrieve key */
zend_hash_get_current_key_zval_ex(target_hash, &args[1], &pos);
/* Move to next element already now -- this mirrors the approach used by foreach
* and ensures proper behavior with regard to modifications. */
zend_hash_move_forward_ex(target_hash, &pos);
/* Back up hash position, as it may change */
EG(ht_iterators)[ht_iter].pos = pos;
and reset pos to get value
/* Reload array and position -- both may have changed */
if (Z_TYPE_P(array) == IS_ARRAY) {
pos = zend_hash_iterator_pos_ex(ht_iter, array);
target_hash = Z_ARRVAL_P(array);
} else if (Z_TYPE_P(array) == IS_OBJECT) {
target_hash = Z_OBJPROP_P(array);
pos = zend_hash_iterator_pos(ht_iter, target_hash);
} else {
php_error_docref(NULL, E_WARNING, "Iterated value is no longer an array or object");
result = FAILURE;
break;
}
- if key= n1; then next pos 1
- if key= n2; then next pos 2
- if key= n3; then next pos 3
when run [$key == 'n2'] , the next pos is 2 ; after unset , pos 2 is unreachable ,so the loop end.
so in actually ,then $key=='n3' will not happen, and u will get the result.