объект LimitIterator - OutOfBoundsException

Как мне написать условие, чтобы не запускать foreach ниже, если объект LimitIterator пуст?

$numbers = array(5, 19, 8, 35, 50);

$iterator = new ArrayIterator($numbers);

$limiter = new LimitIterator($iterator, 5, 2);

foreach($limiter as $number)
{
    echo $number.'<br/>';
}

Приведенный выше код возвращает эту ошибку,

Fatal error: Uncaught exception 'OutOfBoundsException' with message 'Seek position 5 is out of range' in ..
OutOfBoundsException: Seek position 5 is out of range in..

Я просто не хочу запускать foreach, если объект LimitIterator пуст.

ИЗМЕНИТЬ:

Почему $limiter->valid(); всегда возвращает false? У меня есть приведенный ниже код, работающий на странице моего сайта,

$numbers = array(5, 19, 8, 35, 50);

$iterator = new ArrayIterator($numbers);

$limiter = new LimitIterator($iterator, 0, 2);

var_dump($limiter->valid());

if ($limiter->valid()) 
{
    foreach($limiter as $number)
    {
        echo $number.'<br/>';
    }
}

person laukok    schedule 08.07.2011    source источник
comment
Пожалуйста, прекратите писать теги и спасибо.. Я вижу, что вы делаете это для большинства, если не для всех ваших 184 вопросов ;(   -  person Lightness Races in Orbit    schedule 09.07.2011
comment
это правило здесь не благодарить??   -  person laukok    schedule 09.07.2011
comment
Да. SO — это не форум или чат, а ресурс знаний; единственное, что вы видите в вопросе, должно быть вопросом. Вклад в сообщество путем голосования и ответов на вопросы — это большая благодарность. Вы не видите спасибо в словаре.   -  person Lightness Races in Orbit    schedule 09.07.2011


Ответы (2)


OutOfBoundsException выбрасывается, когда LimitIterator пытается найти начальное смещение после перемотки, в самом начале цикла foreach.

Если вы хотите проверить, в порядке ли позиция поиска, то либо rewind(), либо вручную seek() в пределах try/catch блока.

try {
    $limiter->rewind();
} catch (OutOfBoundsException $e) {
    // Do whatever
}

Конечно, вместо этого вы могли бы обернуть цикл foreach в блок try/catch.


Почему $limiter->valid(); всегда возвращает false?

Он не всегда возвращает false, а только тогда, когда он не находится в допустимой позиции.

LimitIterator в вашем скрипте в момент вызова valid() не было сказано перемещаться ни по себе, ни по внутреннему итератору. Пока не будут вызваны rewind() или seek(), они не смогут оказаться в допустимой позиции.

person salathe    schedule 10.07.2011
comment
Я вижу, что вы являетесь авторитетом, поэтому можете ли вы объяснить, почему это не так? не перестать повторяться в конце, как в обычном цикле foreach? Это разрушает функциональность в отношении нумерации страниц. - person drzaus; 31.01.2013

Конечно, если он пуст, foreach не будет работать.

Если вы настаиваете, вы можете проверить правильность первого элемента, как продемонстрировал alex:

$limiter->valid()

но это должно быть совершенно ненужным.

Если ни один из этих подходов не «работает» для вас, значит, что-то еще не так.


Возможно, настоящая проблема заключается в том, что вы не проверяете, действительно ли базовый контейнер содержит семь элементов для итерации.

Я недостаточно знаю об LimitIterator, чтобы быть уверенным, но мой опыт работы с итераторами C++ показывает, что как только вы выходите за разумные границы базового контейнера, все ставки снимаются. Возможно, поэтому $limiter->valid() у вас "не работает"?

person Lightness Races in Orbit    schedule 09.07.2011
comment
он всегда возвращает boolean false, если вы проверяете его с помощью var_dump(), например: var_dump($limiter->valid()); - person laukok; 09.07.2011
comment
@lauthiamkok: не всегда возвращает false. Он возвращает false только тогда, когда текущий элемент недействителен. Вот документация. - person Lightness Races in Orbit; 09.07.2011
comment
Пожалуйста, смотрите мое редактирование выше - можете ли вы объяснить, почему я получаю false? - person laukok; 09.07.2011
comment
@lauthiamkok: (живой пример) Хм, нет. Расследование. - person Lightness Races in Orbit; 09.07.2011
comment
@lauthiamkok: это интересно. Я взял пример из документации, который работает, и добавлена ​​только ссылка на ->valid(), которая возвращает false. Я могу только предположить, что ->valid() либо сломан, либо не делает то, что мы думаем. - person Lightness Races in Orbit; 09.07.2011
comment
возможно, это ошибка PHP! :-) - person laukok; 09.07.2011
comment
@lauthiamkok: Возможно. Обычно я сразу отклоняю такое предложение — предположения о языковых/инфраструктурных ошибках почти всегда оказываются ошибками программиста, — но эта функциональность все еще довольно нова и почти недокументирована. - person Lightness Races in Orbit; 09.07.2011
comment
Без документов это проблема! Я постараюсь обойти эту not to run the foreach проблему! Благодарю. - person laukok; 10.07.2011
comment
@lauthiamkok - это вовсе не ошибка, по крайней мере, отображаемое поведение - это то, что должно произойти. Однако то, что такое поведение (которое не будет ограничено [простите за каламбур] LimitIterator) не задокументировано, является ошибкой в ​​​​документации. - person salathe; 11.07.2011