Как PHP foreach обрабатывает ссылки?

Играя с функцией подсчета ссылок в xdebug, я столкнулся со странным поведением:

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

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

Выход:

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

Почему refcount из a подпрыгивает до трех? Может быть, потому что каждый местный $s держит ссылку на это? Если это тот случай, где он сохраняется? Тогда я вижу, что refcount увеличивается на единицу для первого или второго элемента массива в зависимости от выполняемого цикла. Но почему refcount второй пункт увеличивается на единицу после того, как я сбросил первый?

Ясно, чего я хотел добиться, так это:

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

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

который имеет этот вывод:

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

Можно ли достичь этого результата, используя foreach?

2 ответа

Кроме того, если вы хотите работать только с ссылками, вы можете просто добавить знак "&"(Ampersand) перед обработкой variable.strong text.

Попробуйте следующее, чтобы получить представление о том, что происходит в фоновом режиме:

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

Он выведет все назначенные переменные в любой точке скрипта. Попробуйте переместить его в разные точки вашего файла. Смотрите изменения и вносите коррективы соответственно.

Другие вопросы по тегам