Почему при выгрузке товаров на сайт обрабатываются только категории и импорт зацикливается?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При реализации собственного механизма обмена данными между 1С и сайтом (например, на базе CMS MODX с компонентом mSync) разработчики часто сталкиваются с ситуацией, когда процесс импорта файла import.xml «застревает» на начальном этапе. Система успешно загружает категории товаров, возвращает ответ progress, но при последующих запросах выполнение не переходит к загрузке товаров, а снова и снова обрабатывает только иерархию групп. Разберем детально, почему это происходит и как обеспечить корректную поэтапную обработку данных.

Анализ протокола CommerceML и механизма сессий

Стандартный протокол обмена данными (CommerceML 2) подразумевает, что обработка больших файлов происходит итерациями. Когда скрипт на стороне сайта понимает, что объем данных велик и он не успевает обработать всё за один проход (ограничение max_execution_time в PHP), он сохраняет текущую позицию в файле и возвращает ответ progress. Это сигнал для 1С (или вашего скрипта), что нужно повторить запрос с тем же параметром mode=import.

Проанализируем ситуацию: чтобы сервер «узнал» клиента и понял, на каком шаге тот остановился, должен существовать механизм идентификации. Этим механизмом являются сессии PHP. Рассмотрим стандартный цикл запросов:

  1. Запрос mode=checkauth: Сервер проверяет логин/пароль и возвращает идентификатор сессии.
  2. Запрос mode=init: Передаются параметры обмена (размер архива, поддержка ZIP).
  3. Запрос mode=file: Загрузка XML-файла на сервер.
  4. Запрос mode=import: Команда на начало обработки файла.

Если на шаге 4 сервер возвращает progress, крайне важно, чтобы следующий запрос был отправлен в рамках той же самой сессии. Если сессия теряется, сервер создает новый процесс импорта, который обнуляет все счетчики и снова начинает парсить файл с первой строки — то есть с категорий.

Разбираемся с HTTP-заголовками: Cookie против Set-Cookie

Выясним причину потери сессии, которая часто кроется в путанице между клиентскими и серверными заголовками. Проанализируем ошибку, допущенную автором темы. При обмене данными используются два типа заголовков для работы с куками:

Если при разработке своей выгрузки вы ошибочно передаете серверу заголовок Set-Cookie вместо Cookie, сервер просто проигнорирует этот параметр. В результате PHP не сможет восстановить сессию (переменную $_SESSION), в которой компонент mSync или ваш скрипт хранит состояние импорта (например, смещение в байтах или количество обработанных товаров). Импорт начнется заново, обработает категории и снова выдаст progress. Получится бесконечный цикл.

Корректная передача идентификатора сессии

Рассмотрим пример того, как должен выглядеть заголовок в вашем HTTP-запросе после того, как вы получили авторизацию. Предположим, сервер вернул вам PHPSESSID=abc123xyz.

Ваш следующий запрос должен содержать строку:

Cookie: PHPSESSID=abc123xyz;

В коде 1С при использовании объекта HTTPЗапрос это реализуется установкой заголовка:


Запрос = Новый HTTPЗапрос(ПутьКФайлу);
Запрос.Заголовки.Вставить("Cookie", ИдентификаторСессии);

Где ИдентификаторСессии — это строка вида "PHPSESSID=...", полученная из ответа сервера на шаге checkauth.

Особенности компонента mSync и временных таблиц

Если вы используете MODX и mSync, проанализируем логи, приведенные в теме. Мы видим строки Начат импорт категорий... во временную таблицу. Это важный момент: mSync работает через промежуточное хранилище в базе данных. Процесс разбит на этапы:

  1. importCategories — парсинг категорий во временную таблицу.
  2. importProperties — обработка характеристик (свойств).
  3. importProducts — загрузка самих товаров.

Если сессия настроена верно, но импорт всё равно стоит на месте, проверим права доступа пользователя базы данных. Скрипт должен иметь права на выполнение команд CREATE TEMPORARY TABLES и TRUNCATE. В логе автора видно, что категории успешно выгружаются (10 штук), но переход к следующему шагу (параметры lastProduct, totalProducts) не происходит из-за сброса состояния сессии.

Проверка настроек сервера PHP

Иногда проблема кроется не в коде выгрузки, а в конфигурации самого сервера. Рассмотрим критические параметры:

Итоговый алгоритм отладки

Чтобы окончательно решить проблему зацикливания, рекомендуем выполнить следующие шаги:

  1. Проверьте логи сервера: Убедитесь, что в каждом запросе mode=import передается один и тот же PHPSESSID.
  2. Сверьте заголовки: Замените Set-Cookie на Cookie в исходящих запросах вашего скрипта.
  3. Увеличьте лимиты: В настройках mSync (или вашей системы) попробуйте временно увеличить количество товаров, обрабатываемых за один шаг, и одновременно увеличьте memory_limit в .htaccess или php.ini.
  4. Очистите временные файлы: Удалите содержимое папки 1c_temp и очистите временные таблицы в БД, чтобы исключить влияние «мусорных» данных от предыдущих неудачных попыток.

Соблюдение этих правил позволит корректно реализовать стандарт CommerceML и обеспечит стабильную выгрузку даже очень больших каталогов товаров на ваш сайт.

← На главную