Налаштування масового завантаження фотографій товарів 1С-Бітрікс
Каталог із 20 000 позицій, у кожної потрібно замінити головне фото та додати галерею з 5–8 знімків. Через адміністративний інтерфейс це кілька людино-тижнів ручної праці. На практиці завдання вирішується за кілька годин за допомогою API Бітрікс та пакетної обробки.
Де зберігаються фотографії в Бітрікс
Файли товарних зображень зберігаються в таблиці b_file. Кожен файл має свій ID. Інфоблок (каталог) посилається на них через властивості:
-
PREVIEW_PICTURE— анонсове зображення, зберігається вb_iblock_element.PREVIEW_PICTURE(FK наb_file.ID) -
DETAIL_PICTURE— детальне зображення,b_iblock_element.DETAIL_PICTURE - Властивість типу «Файл/Картинка» —
b_iblock_element_property.VALUEз посиланням наb_file.ID
Множинні зображення (галерея) — через властивість типу «Картинка» з прапорцем «Множинне». Для торгових пропозицій — ті самі поля в контексті елемента торгової пропозиції.
Підготовка файлів
Зображення потрібно підготувати заздалегідь: структура директорій за артикулом, однакове найменування. Зручна схема:
/import/images/
sku_001/
main.jpg
2.jpg
3.jpg
sku_002/
main.jpg
Якщо файли надходять із 1С — імена зазвичай збігаються з XML_ID елемента. Якщо з фотостудії — потрібна карта відповідності (CSV: артикул → імена файлів).
Завантаження через CFile та CIBlockElement
Базовий підхід: читаємо CSV з маппінгом, для кожного рядка завантажуємо файл через CFile::SaveFile() і оновлюємо елемент.
$csvRows = parseCsv('/import/mapping.csv'); // [['xml_id' => 'sku_001', 'files' => ['main.jpg', '2.jpg']]]
foreach ($csvRows as $row) {
// Знаходимо елемент за XML_ID
$element = \Bitrix\Iblock\ElementTable::getList([
'filter' => ['XML_ID' => $row['xml_id'], 'IBLOCK_ID' => CATALOG_IBLOCK_ID],
'select' => ['ID'],
])->fetch();
if (!$element) continue;
$imageDir = '/import/images/' . $row['xml_id'] . '/';
$files = [];
foreach ($row['files'] as $i => $filename) {
$filePath = $imageDir . $filename;
if (!file_exists($filePath)) continue;
$fileId = \CFile::SaveFile([
'name' => $filename,
'type' => mime_content_type($filePath),
'tmp_name' => $filePath,
'error' => 0,
'size' => filesize($filePath),
], 'iblock');
if ($i === 0) {
// Перший файл — головне зображення
\CIBlockElement::Update($element['ID'], [
'PREVIEW_PICTURE' => \CFile::MakeFileArray($filePath),
'DETAIL_PICTURE' => \CFile::MakeFileArray($filePath),
]);
} else {
$files[] = ['VALUE' => \CFile::MakeFileArray($filePath)];
}
}
// Множинна властивість галереї
if (!empty($files)) {
\CIBlockElement::SetPropertyValues($element['ID'], CATALOG_IBLOCK_ID, $files, 'MORE_PHOTO');
}
}
CFile::MakeFileArray() не копіює файл — це просто масив-дескриптор. CFile::SaveFile() — фактичне збереження та запис до b_file.
Продуктивність на великих обсягах
На каталозі 20 000+ позицій прямий цикл працюватиме 2–4 години та може впасти через тайм-аут або ліміт пам'яті. Кілька правил:
Розбивайте на пакети. Обробляйте по 200–500 елементів за ітерацію, зберігайте прогрес у файл або таблицю.
Вимикайте зайві обробники подій. При масовому оновленні події OnBeforeIBlockElementUpdate та OnAfterIBlockElementUpdate можуть викликати ланцюжок важких операцій (перерахунок цін, інвалідація кешу, оновлення пошуку). Тимчасово вимкніть агентів та події, якщо вони не потрібні під час імпорту:
define('BX_DONT_PROCESS_EVENTS', true); // тільки якщо точно знаєте наслідки
// АБО точково:
\Bitrix\Main\EventManager::getInstance()->removeEventHandler('iblock', 'OnAfterIBlockElementUpdate', $handlerId);
Використовуйте CLI-скрипти. Запускайте через php -f import_images.php — немає обмежень за часом виконання веб-запиту. Увімкніть set_time_limit(0) та ini_set('memory_limit', '512M').
Очищайте кеш після завершення. Після масового завантаження скиньте кеш інфоблоків: \Bitrix\Iblock\InformationBlock::cleanTagCache($iblockId). Не робіть це всередині циклу — лише один раз наприкінці.
Обробка помилок та логування
$log = fopen('/var/log/image_import.log', 'a');
foreach ($csvRows as $row) {
try {
// ... обробка
fwrite($log, date('Y-m-d H:i:s') . " OK: {$row['xml_id']}\n");
} catch (\Throwable $e) {
fwrite($log, date('Y-m-d H:i:s') . " ERR: {$row['xml_id']} — {$e->getMessage()}\n");
}
}
Часті помилки: файл не знайдено, невірний MIME-тип, дублікат у b_file (Бітрікс перевіряє за хешем — повторне завантаження того самого файлу поверне наявний ID).
Генерація мініатюр
Після завантаження Бітрікс створює мініатюри ліниво — при першому зверненні через компонент. Якщо потрібно прогріти кеш одразу:
\CFile::ResizeImageGet($fileId, ['width' => 400, 'height' => 400], BX_RESIZE_IMAGE_PROPORTIONAL, true);
Або через CLI-утиліту, якщо на сервері налаштовано модуль ImageMagick.
Терміни виконання
| Обсяг каталогу | Орієнтовний час |
|---|---|
| До 1 000 товарів | 1–2 години (налаштування + завантаження) |
| 1 000–10 000 товарів | 4–8 годин |
| 10 000–50 000 товарів | 1–2 дні (включно з тестуванням та прогрівом кешу) |







