При реализации собственного механизма обмена данными между 1С и сайтом (например, на базе CMS MODX с компонентом mSync) разработчики часто сталкиваются с ситуацией, когда процесс импорта файла import.xml «застревает» на начальном этапе. Система успешно загружает категории товаров, возвращает ответ progress, но при последующих запросах выполнение не переходит к загрузке товаров, а снова и снова обрабатывает только иерархию групп. Разберем детально, почему это происходит и как обеспечить корректную поэтапную обработку данных.
Стандартный протокол обмена данными (CommerceML 2) подразумевает, что обработка больших файлов происходит итерациями. Когда скрипт на стороне сайта понимает, что объем данных велик и он не успевает обработать всё за один проход (ограничение max_execution_time в PHP), он сохраняет текущую позицию в файле и возвращает ответ progress. Это сигнал для 1С (или вашего скрипта), что нужно повторить запрос с тем же параметром mode=import.
Проанализируем ситуацию: чтобы сервер «узнал» клиента и понял, на каком шаге тот остановился, должен существовать механизм идентификации. Этим механизмом являются сессии PHP. Рассмотрим стандартный цикл запросов:
mode=checkauth: Сервер проверяет логин/пароль и возвращает идентификатор сессии.mode=init: Передаются параметры обмена (размер архива, поддержка ZIP).mode=file: Загрузка XML-файла на сервер.mode=import: Команда на начало обработки файла.Если на шаге 4 сервер возвращает progress, крайне важно, чтобы следующий запрос был отправлен в рамках той же самой сессии. Если сессия теряется, сервер создает новый процесс импорта, который обнуляет все счетчики и снова начинает парсить файл с первой строки — то есть с категорий.
Выясним причину потери сессии, которая часто кроется в путанице между клиентскими и серверными заголовками. Проанализируем ошибку, допущенную автором темы. При обмене данными используются два типа заголовков для работы с куками:
Если при разработке своей выгрузки вы ошибочно передаете серверу заголовок Set-Cookie вместо Cookie, сервер просто проигнорирует этот параметр. В результате PHP не сможет восстановить сессию (переменную $_SESSION), в которой компонент mSync или ваш скрипт хранит состояние импорта (например, смещение в байтах или количество обработанных товаров). Импорт начнется заново, обработает категории и снова выдаст progress. Получится бесконечный цикл.
Рассмотрим пример того, как должен выглядеть заголовок в вашем HTTP-запросе после того, как вы получили авторизацию. Предположим, сервер вернул вам PHPSESSID=abc123xyz.
Ваш следующий запрос должен содержать строку:
Cookie: PHPSESSID=abc123xyz;
В коде 1С при использовании объекта HTTPЗапрос это реализуется установкой заголовка:
Запрос = Новый HTTPЗапрос(ПутьКФайлу);
Запрос.Заголовки.Вставить("Cookie", ИдентификаторСессии);
Где ИдентификаторСессии — это строка вида "PHPSESSID=...", полученная из ответа сервера на шаге checkauth.
Если вы используете MODX и mSync, проанализируем логи, приведенные в теме. Мы видим строки Начат импорт категорий... во временную таблицу. Это важный момент: mSync работает через промежуточное хранилище в базе данных. Процесс разбит на этапы:
importCategories — парсинг категорий во временную таблицу.importProperties — обработка характеристик (свойств).importProducts — загрузка самих товаров.Если сессия настроена верно, но импорт всё равно стоит на месте, проверим права доступа пользователя базы данных. Скрипт должен иметь права на выполнение команд CREATE TEMPORARY TABLES и TRUNCATE. В логе автора видно, что категории успешно выгружаются (10 штук), но переход к следующему шагу (параметры lastProduct, totalProducts) не происходит из-за сброса состояния сессии.
Иногда проблема кроется не в коде выгрузки, а в конфигурации самого сервера. Рассмотрим критические параметры:
import.xml весит десятки мегабайт, SimpleXML может потреблять в 5-10 раз больше оперативной памяти. Если лимит превышен, скрипт «тихо» падает, не успев сохранить прогресс.Чтобы окончательно решить проблему зацикливания, рекомендуем выполнить следующие шаги:
mode=import передается один и тот же PHPSESSID.Set-Cookie на Cookie в исходящих запросах вашего скрипта.mSync (или вашей системы) попробуйте временно увеличить количество товаров, обрабатываемых за один шаг, и одновременно увеличьте memory_limit в .htaccess или php.ini.1c_temp и очистите временные таблицы в БД, чтобы исключить влияние «мусорных» данных от предыдущих неудачных попыток.Соблюдение этих правил позволит корректно реализовать стандарт CommerceML и обеспечит стабильную выгрузку даже очень больших каталогов товаров на ваш сайт.