2016-07-22 2 views
2

Я всегда теряю второй элемент (# 1) в forearh из ArrayIterator и удаляя каждый элемент.php: всегда теряет элемент # 1 в ArrayIterator с использованием ArrayIterator :: offsetUnset для текущего элемента в цикле

$cnt = 0; 
$a = new ArrayIterator(); 
$a->append(++$cnt); 
$a->append(++$cnt); 
$a->append(++$cnt); 
$a->append(++$cnt); 
$a->append(++$cnt); 

foreach ($a as $i => $item) { 
    print_r("$i => $item".PHP_EOL); 
    $a->offsetUnset($i); 
} 
print_r('count: '.$a->count().PHP_EOL); 

foreach ($a as $i => $item) { 
    print_r("lost! $i => $item".PHP_EOL); 
} 

Выход:

0 => 1 
2 => 3 
3 => 4 
4 => 5 
count: 1 
lost! 1 => 2 

Как это возможно? оо

$ php -v 
PHP 5.5.37 (cli) (built: Jun 22 2016 16:14:46) 
Copyright (c) 1997-2015 The PHP Group 
Zend Engine v2.5.0, Copyright (c) 1998-2015 Zend Technologies 

ответ

0

Кажитесь, есть только исчерпывают ArrayIterator методом offsetUnset. Вот с помощью do..while:

do { 
    print_r("{$a->key()} => {$a->current()}".PHP_EOL); 
    $a->offsetUnset($a->key()); 
} while ($a->count()); 
print_r('count: '.$a->count() . PHP_EOL); 

Выходные:

0 => 1 
1 => 2 
2 => 3 
3 => 4 
4 => 5 
count: 0 
1

Поздравляем! Вы нашли documented bug in ArrayIterator

экстракт:

ArrayIterator всегда пропускает второй элемент в массиве при вызове offsetUnset(); на нем во время цикла.

Использование ключа с итератора и снятие с охраны в фактическом объекте ArrayObject работает как .

+0

Хорошо, спасибо за обнаружение ошибки. Я не знал об этом. – Kirby