PHP的foreach如何处理引用?

While playing with xdebug's reference counting feature, i came across this strange behaviour:

$a = array('foo', 'bar');
xdebug_debug_zval('a');

foreach ($a as $key => $s) {
    xdebug_debug_zval('a');
    echo "$s
";
    unset($a[$key]);
    xdebug_debug_zval('a');
}

The output is:

a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='foo', 1 => (refcount=1, is_ref=0)='bar')
a: (refcount=3, is_ref=0)=array (0 => (refcount=2, is_ref=0)='foo', 1 => (refcount=1, is_ref=0)='bar')
foo
a: (refcount=1, is_ref=0)=array (1 => (refcount=2, is_ref=0)='bar')
a: (refcount=1, is_ref=0)=array (1 => (refcount=3, is_ref=0)='bar')
bar
a: (refcount=1, is_ref=0)=array ()

Why does refcount of a jumps up to three? Maybe because each local $s keeps a reference to it? If this is the case where is it saved? Then i see that refcount is increased by one for either the first or the second item of the array, depending on the cycle being executed. But why refcount of the second item is increased by one after i unset the first one?

Clearly, what i wanted to achieve is this:

$a = array('foo', 'bar');
xdebug_debug_zval('a');

$tot = count($a);
for ($i = 0; $i < $tot; $i++) {
    xdebug_debug_zval('a');
    echo $a[$i]."
";
    unset($a[$i]);
    xdebug_debug_zval('a');
}

which has this output:

a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='foo', 1 => (refcount=1, is_ref=0)='bar')
a: (refcount=1, is_ref=0)=array (0 => (refcount=1, is_ref=0)='foo', 1 => (refcount=1, is_ref=0)='bar')
foo
a: (refcount=1, is_ref=0)=array (1 => (refcount=1, is_ref=0)='bar')
a: (refcount=1, is_ref=0)=array (1 => (refcount=1, is_ref=0)='bar')
bar
a: (refcount=1, is_ref=0)=array ()

Is it possible to achieve this result using foreach?

Try the following to get a handle on what is going in the background:

print_r(array_keys(get_defined_vars()));
print_r(array_values(get_defined_vars()));

It will output all assigned variables at any given point in a script. Try moving it to different points in your file. See the changes and make adjustments accordingly.

Besides if you want to work with only references then you can simply add the "&"(Ampersand) sign before the handling variable.strong text