PHP - Цикл через набор записей и запуск события каждые n строк

Я ищу правильную логику для циклического прохождения набора записей и запуска события каждые n раз.

Поискав в Google, я нашел обсуждение подобных ситуаций, но кажется, что решения не соответствуют моим потребностям.

Мне нужно связать мое приложение с веб-сервисом, который использует minOccurs="0" maxOccurs="4" для повторяющихся элементов в одном вызове. Допустим, у меня есть набор записей из 22 строк.

Мне необходимо:

  1. прокручивать набор записей и заполнять массив $data каждой строкой
  2. в 4-й строке (8-й, 12-й, 16-й...) запустить событие (вызвать WS с $data из 4 элементов)
  3. очистить $data и продолжить цикл до следующего 4-го
  4. если количество строк не кратно 4, я должен обработать остаток и запустить последний вызов

Используя оператор модуля, как показано в этом ответе, if($i % 4 == 0) я получаю событие запускает каждые 4 строки, но 22 не кратны 4, поэтому событие запускается до 20-й строки, а затем ничего. Может быть, мне нужно сделать деление, считая строки «лишними»?

Поскольку набор записей будет от 50 до 200 строк, я думаю, что нет необходимости запускать несколько запросов из 4 строк, я ошибаюсь?

Заранее спасибо!

ОБНОВЛЕНИЕ: Вдохновленный приведенными ниже ответами, мне наконец удалось заставить скрипт работать так, как я хотел... возможно, это не элегантное решение, но работает так, как ожидалось:

$result = $query->result(); // the recordset
$total_rows = count($result);
$interleave = 4;
$reminder = $total_rows % $interleave;
$round_rows = ($total_rows-$reminder)+1; // +1 because $i dont start at zero
$data = array();

Начните с начального цикла ($round_rows кратно 4)

for ($i=1; $i<$round_rows; $i++){
            $data[$i] = $result[$i];
            if ($i % $interleave == 0){
                $this->fire_event($data);
                $data = array();
            }
 }

Затем, если есть напоминание, прокрутите...

if ($total_rows % $interleave !== 0){
            for ($i = $round_rows; $i < $total_rows + 1; $i++) {
                $data[$i] = $result[$i];
            }
            $this->fire_event($data);
}

Любые советы приветствуются!


person Luciano    schedule 28.03.2012    source источник
comment
Вы нашли правильный путь. Если до 22, то почему он должен срабатывать в 21 и 22?   -  person aletzo    schedule 28.03.2012
comment
Если вы хотите, чтобы событие запускалось каждые 4 строки, зачем вам вообще нужно, чтобы оно запускалось в строке 22? Кроме того, что за событие? Вы что-то вычисляете?   -  person R2-Bacca    schedule 28.03.2012
comment
Почему вы хотите, чтобы он срабатывал в строке 22?   -  person Martin.    schedule 28.03.2012
comment
Зачем вам запускать его на последнем, если он не делится на 4?   -  person Sujit Agarwal    schedule 28.03.2012
comment
@ R2-Bacca: Извините, я забыл сказать, что мне нужно запустить событие даже в конце цикла. Я собираюсь обновить вопрос ...   -  person Luciano    schedule 28.03.2012
comment
У меня было ощущение, что ты хотел сделать что-то подобное. Ответ @Eineki ниже правильный. Все, что вам нужно сделать, это запустить событие в конце цикла (полностью вне фигурных скобок цикла for(whatever){blah} fire_my_event();   -  person R2-Bacca    schedule 28.03.2012


Ответы (1)


Если вам нужно запустить событие в конце набора записей, просто сделайте это.

for($i=0 .... ) {
 // do yourcalculation
}

//fire your event for the end of the recordset

Если вам нужно запустить событие только тогда, когда у вас есть запасные записи после последнего запущенного события, используйте if

$interleave = 4; // or whaterver you interval you need
for($i=0 .... ) {
 // do yourcalculation
}

if (!($i % $interleave)) {
    // fire your event
}

Индекс $i продолжает жить после окончания цикла, и вы можете использовать это свойство языка.

person Eineki    schedule 28.03.2012