Картинки товара - загрузка, размеры и вывод галереи
Разбираемся, как хранятся и выводятся изображения товара, и убираем две частые беды: медленную карточку и отказ загрузки.
Решение
Смотрим, что лежит в полях картинок:
$res = CIBlockElement::GetList([], ['IBLOCK_ID' => 5, 'ID' => $elementId], false, false, ['ID', 'PREVIEW_PICTURE', 'DETAIL_PICTURE', 'PROPERTY_MORE_PHOTO']);$row = $res->Fetch();printf("анонс=%s детальная=%s доп=%s\n", $row['PREVIEW_PICTURE'] ?: '-', $row['DETAIL_PICTURE'] ?: '-', $row['PROPERTY_MORE_PHOTO_VALUE'] ?: '-');В полях лежат идентификаторы файлов, а не пути к ним. Путь получают отдельным вызовом, и этот же вызов умеет сразу отдать уменьшенную копию нужного размера.
Отдаём уменьшенные копии вместо исходников:
$img = CFile::ResizeImageGet($row['DETAIL_PICTURE'], ['width' => 600, 'height' => 600], BX_RESIZE_IMAGE_PROPORTIONAL, true);printf('<img src="%s" width="%d" height="%d" alt="">', $img['src'], $img['width'], $img['height']);// размеры в разметке избавляют страницу от прыжков при загрузкеУменьшенная копия создаётся один раз и складывается рядом с исходником. Прямая выдача исходного файла на десять мегабайт - самая частая причина медленной карточки, и лечится она именно здесь, а не настройками сервера.
Выводим галерею дополнительных картинок товара:
foreach ((array)$row['PROPERTY_MORE_PHOTO_VALUE'] as $fileId) { $small = CFile::ResizeImageGet($fileId, ['width' => 120, 'height' => 120], BX_RESIZE_IMAGE_EXACT, true); printf('<img src="%s" alt="">' . "\n", $small['src']);}Дополнительные картинки хранятся обычным множественным свойством. Порядок в галерее - это порядок значений свойства, и меняют его пересохранением всего набора, а не сортировкой при выводе.
Проверяем, почему не грузятся новые файлы:
ls -ld /home/bitrix/www/upload/ /home/bitrix/www/upload/iblock/df -h /home/bitrixphp -i | grep -E 'upload_max_filesize|post_max_size|memory_limit'# памяти должно хватать не только на файл, но и на его разворот при ресайзе# каталог загрузок должен принадлежать пользователю процессов сайтаОтказ загрузки почти всегда упирается в одно из трёх: права на папку загрузок, кончившееся место на диске или предел размера файла. Сообщение в интерфейсе при этом одинаковое сразу для всех трёх случаев отказа.
Размеры копий стоит задавать один раз и держать их список по возможности коротким. Каждый новый размер - это ещё один файл на диске у каждого товара, и на каталоге в десятки тысяч позиций разница в занятом месте выходит ощутимой.
Создание уменьшенной копии тоже стоит памяти процессу. Изображение на двадцать мегапикселей при уменьшении разворачивается в памяти целиком, и при низком пределе процесс просто падает - картинка при этом остаётся исходной.
Удалённые из свойства файлы физически остаются лежать на диске самого сервера. Место они занимают до отдельной чистки, и на каталоге, который переносили несколько раз, такие файлы легко набирают десятки гигабайтов.
Типичные проблемы
В шаблоне выводится число вместо картинки.
В поле картинки лежит идентификатор файла, а не путь. Сам путь получают отдельным вызовом по этому идентификатору.
Карточка товара грузится долго.
В шаблоне выводятся исходные файлы вместо уменьшенных копий. Копию нужного размера создают вызовом изменения размера.
Файл не загружается без внятной ошибки.
Нет прав на папку загрузок, кончилось место на диске либо файл больше предела. Интерфейс сообщает обо всех трёх случаях совершенно одинаково.
Уменьшенная копия не создалась.
Процессу не хватило памяти на разворот большого изображения. В карточке в таком случае остаётся исходный файл.
Папка загрузок разрослась.
Файлы, удалённые из свойств, физически остаются на диске. Их убирает отдельная процедура чистки неиспользуемых файлов.
Частые вопросы
Где хранятся уменьшенные копии?
Рядом с исходником, в подпапке кэша изображений. Они создаются при первом обращении и переживают обычную чистку кэша страниц.
Как задать свои размеры для витрины и карточки?
Параметрами компонентов: у списка и у детальной страницы свои настройки размеров. Значения подбирают под шаблон, а не берут наугад.
Можно ли грузить картинки по ссылке?
Да, платформа умеет принимать файл по адресу и класть его к себе. Так делают массовую загрузку из внешних источников.
Что делать с исходниками после ресайза?
Хранить: копии создаются из них, и при смене размеров в шаблоне исходник понадобится снова.
Смежное
- Каталог товаров - оглавление подтемы
- Карточка товара: вывод свойств, картинок и характеристик - где выводится галерея
- Картинки товара при обмене: детальная, дополнительные, разделы - откуда картинки приезжают
- Файл не загружается: пределы, права, типы, веб-сервер - общий разбор отказов загрузки
- Быстрые картинки на витрине: размеры, ленивая загрузка, WebP - те же картинки со стороны скорости
- Каталог и продажи - устройство магазина целиком
- Права на файлы и папки: файловая система и права структуры - права на папку загрузок
- Папка загрузок растёт: дубли картинок и лишние файлы - разбор растущей папки загрузок
- Картинки торговых предложений: смена при выборе варианта - картинки у вариантов товара
- Файлы из кода: сохранение, уменьшенные копии, удаление - тот же механизм вне каталога