Как 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()));
Он выведет все назначенные переменные в любой точке скрипта. Попробуйте переместить его в разные точки вашего файла. Смотрите изменения и вносите коррективы соответственно.