Итератор
Итератор выполняет длительные операции по частям и сохраняет состояние между запусками.
Создать итератор
Итератор реализован в базовом классе \Bitrix\Main\Update\Stepper. Чтобы настроить свой итератор, создайте новый класс-наследник.
-
Укажите идентификатор модуля.
-
Реализуйте метод
execute(array &$option). -
Укажите, когда продолжить или завершить выполнение итератора с помощью констант
self::CONTINUE_EXECUTIONиself::FINISH_EXECUTION.
Один вызов execute() обрабатывает порцию элементов и увеличивает steps на количество обработанных элементов.
<?php
namespace MyCompany\MyModule\Stepper;
use Bitrix\Main\Update\Stepper;
class ExampleStepper extends Stepper
{
protected static $moduleId = 'mycompany.mymodule';
// За один запуск обработаем один шаг и увеличим счетчик прогресса.
public function execute(array &$option)
{
if (empty($option))
{
$option['steps'] = 0; // сколько обработано
$option['count'] = 100; // всего шагов
}
$option["steps"]++;
// Используем константы для указания статуса выполнения
return ($option['steps'] < $option['count'])
? self::CONTINUE_EXECUTION
: self::FINISH_EXECUTION;
}
// Переопределяем метод для отображения своего заголовка
public static function getTitle()
{
return 'Пример обработки';
}
}
Переопределяйте заголовок методом getTitle(), если нужно показывать свое название в интерфейсе.
Для одноразовых задач в класс можно добавить свойство $deleteFile со значением true. После завершения работы система удалит файл класса.
protected $deleteFile = true;
Запустить итератор
Итератор запускается как отложенный агент. Система выполняет его при каждом запросе к сайту, но не чаще одного раза в секунду.
Подробнее в статье Агенты и фоновые задачи
Для создания агента можно использовать один из двух методов.
-
bind($delay, $withArguments)— создает агента для текущего класса. Используйте, когда модуль уже загружен, например, в обработчике события или в компоненте.-
$delay— задержка в секундах перед первым запуском. Значение по умолчанию —300. -
$withArguments— массив параметров для передачи в итератор.
// Запустить через 120 секунд if (\Bitrix\Main\Loader::includeModule('mycompany.mymodule')) { \MyCompany\MyModule\Stepper\ExampleStepper::bind(120); } -
-
bindClass($className, $moduleId, $delay, $withArguments)— создает агента для указанного класса и модуля. Используйте в файлах установки модуля или когда модуль может быть не загружен.-
$className— полное имя класса итератора. -
$moduleId— идентификатор модуля, к которому привязан итератор. -
$delay— задержка в секундах перед первым запуском. Значение по умолчанию —300. -
$withArguments— массив параметров для передачи в итератор.
\Bitrix\Main\Update\Stepper::bindClass( 'MyCompany\MyModule\Stepper\ExampleStepper', 'mycompany.mymodule', 60 ); -
Передать параметры в итератор
Передавайте параметры через $withArguments, если хотите запускать один и тот же Stepper с разными входными данными.
В массиве используйте простые типы: строку или целое число.
// Запуск с параметрами
\Bitrix\Main\Update\Stepper::bindClass(
'MyCompany\MyModule\Stepper\DataProcessor',
'mycompany.mymodule',
120,
[
'category_id' => 5,
'action' => 'export',
'limit' => 1000,
]
);
Получить параметры можно методом getOuterParams().
// Получение параметров в итераторе
public function execute(array &$option)
{
$params = $this->getOuterParams();
$categoryId = (int)($params['category_id'] ?? 0);
$action = $params['action'] ?? '';
// Используем параметры в логике
}
Показать прогресс выполнения
Прогресс выполнения итераторов отображается с помощью элемента Градусник. Он показывает соотношение пройденных шагов к общему количеству шагов.

-
Конкретный итератор — показывает прогресс только одного итератора. Используйте, чтобы отобразить статус конкретной операции.
echo \MyCompany\MyModule\Stepper\ExampleStepper::getHtml(); -
Все итераторы модуля — показывает общий прогресс всех итераторов модуля. Можно использовать для административной страницы модуля.
echo \Bitrix\Main\Update\Stepper::getHtml( 'mycompany.mymodule', 'Обработка данных модуля' ); -
Выборочные итераторы — показывает прогресс только указанных итераторов. Используйте, когда нужно сгруппировать связанные операции.
echo \Bitrix\Main\Update\Stepper::getHtml([ 'mycompany.mymodule' => [ 'MyCompany\MyModule\Stepper\DataMigrator', 'MyCompany\MyModule\Stepper\CacheClear', ], 'iblock' => [ 'Bitrix\Iblock\Stepper\SomeProcessor', ], ], 'Фоновая обработка');
Градусник опрашивает сервер о состоянии каждые пять минут, когда отображается на странице.
Сохранить прогресс выполнения
Прогресс выполнения итератора между запусками можно хранить в массиве $option.
-
steps— количество выполненных шагов. -
count— общее количество шагов. -
другие данные для продолжения работы, например, последний обработанный
ID.
Данные о шагах steps и count нужны для отображения прогресса в Градуснике.
public function execute(array &$option)
{
if (empty($option))
{
// Инициализация при первом запуске
$option['steps'] = 0; // количество выполненных шагов
$option['count'] = $this->calculateTotalItems(); // общее количество шагов
$option['last_processed_id'] = 0;
$option['processed_ids'] = [];
}
// Используем сохраненные данные
$lastId = (int)$option['last_processed_id'];
// Обрабатываем следующую порцию
$processed = $this->processNextBatch($lastId, 50);
// Сохраняем состояние для следующего запуска
$option['last_processed_id'] = $processed['last_id'];
$option['steps'] += $processed['count'];
$option['processed_ids'] = array_merge(
$option['processed_ids'],
$processed['ids']
);
// Проверяем завершение
return ($option['steps'] < $option['count'])
? self::CONTINUE_EXECUTION
: self::FINISH_EXECUTION;
}
Не рекомендуется хранить большие объемы данных в массиве $option, так как массив сериализуется при каждом сохранении.