Оптимизация запросов файлов
Если использовать стандартные компоненты и примеры кода, то запросы будут идти в цикле, что не оптимально. Покажу как сделать все одним запросом.
Стандартно это выглядит примерно так:$arItems = []; $dbItem = CIBlockElement::GetList( ['SORT' => 'ASC'], ['ACTIVE' => 'Y', 'IBLOCK_ID' => $arIblock['ID']], false, false, ['ID', 'IBLOCK_ID', 'PREVIEW_PICTURE'] ); while ($arItem = $dbItem->GetNext()) { if ($arItem['PREVIEW_PICTURE']) { // Запрос в цикле $file = CFile::ResizeImageGet($arItem['PREVIEW_PICTURE'], array('width' => 400, 'height' => 400), BX_RESIZE_IMAGE_PROPORTIONAL, true); } $arItems[] = $arItem; }
Т.к. CIBlockElement::GetList возвращает только ID из поля PREVIEW_PICTURE, то метод CFile::ResizeImageGet делает запрос в БД, получая все параметры файла. Получается по одному запросу на каждый файл.
Нужно немного поменять код, собрав все ID файлов, и сделав один запрос за всеми файлами сразу:
$arItems = []; $arPicturesId = []; $dbItem = CIBlockElement::GetList( ['SORT' => 'ASC'], ['ACTIVE' => 'Y', 'IBLOCK_ID' => $arIblock['ID']], false, false, ['ID', 'IBLOCK_ID', 'PREVIEW_PICTURE'] ); while ($arItem = $dbItem->GetNext()) { if ($arItem['PREVIEW_PICTURE']) { $arPicturesId[] = $arItem['PREVIEW_PICTURE']; } $arItems[] = $arItem; } $arFiles = []; if ($arPicturesId) { // Все картинки одним запросом $dbFile = CFile::GetList( [], ['@ID' => implode(',', $arPicturesId)] ); while ($arFile = $dbFile->Fetch()) { $arFiles[$arFile['ID']] = $arFile; } } foreach ($arItems as $arItem) { if ($arItem['PREVIEW_PICTURE']) { $file = CFile::ResizeImageGet($arFiles[$arItem['PREVIEW_PICTURE']] ?: $arItem['PREVIEW_PICTURE'], array('width' => 400, 'height' => 400), BX_RESIZE_IMAGE_PROPORTIONAL, true); } }
Т.к. в CFile::ResizeImageGet передаётся уже массив данных файла, то метод не будет делать запрос, а сразу перейдёт к "ресайзу" картинки
Есть вопросы или нашли ошибку? Напишите комментарий (можно без регистрации), отвечать стараюсь быстро.