Работа с файлами в Битрикс: загрузка, resize и удаление через API

Работа с файлами в Битрикс — это не просто сохранение в папку upload. У ядра есть собственный механизм с таблицей b_file, который управляет правами доступа, изменением размера и кэшированием.

Загрузка файла через API

// Загрузка из $_FILES
$fileId = \CFile::SaveFile([
    'name'     => $_FILES['photo']['name'],
    'size'     => $_FILES['photo']['size'],
    'tmp_name'=> $_FILES['photo']['tmp_name'],
    'type'     => $_FILES['photo']['type'],
], 'catalog');  // подпапка в /upload/

if ($fileId) {
    echo 'Файл сохранён с ID: ' . $fileId;
}

// Загрузка из пути на диске
$fileId = \CFile::SaveFile(
    \CFile::MakeFileArray('/path/to/local/file.jpg'),
    'import'
);

Получение информации о файле

// По ID из базы
$fileInfo = \CFile::GetFileArray($fileId);

echo $fileInfo['SRC'];      // путь к файлу: /upload/catalog/photo.jpg
echo $fileInfo['WIDTH'];    // ширина (для изображений)
echo $fileInfo['HEIGHT'];   // высота
echo $fileInfo['FILE_SIZE']; // размер в байтах
echo $fileInfo['CONTENT_TYPE']; // image/jpeg

// Получить полный URL
echo \CFile::GetFileSRC($fileInfo);

Resize изображения

// Уменьшить до 800x600 с сохранением пропорций
$resized = \CFile::ResizeImageGet($fileId, ['width' => 800, 'height' => 600], BX_RESIZE_IMAGE_PROPORTIONAL);

echo $resized['src']; // путь к уменьшенному изображению

// Через D7
$image = \Bitrix\Main\UI\Crop::cropImage(
    $fileInfo['SRC'],
    ['width' => 300, 'height' => 300, 'exact' => true]
);

// Ещё один способ через ResizeImageGet
\CFile::ResizeImageGet(
    $fileId,
    ['width' => 400, 'height' => 300],
    BX_RESIZE_IMAGE_EXACT,  // точный размер с обрезкой
    true,                   // использовать webp
    false,                  // не сохранять в файл
);

Привязка файла к свойству инфоблока

// При добавлении элемента инфоблока
$el = new \CIBlockElement();
$result = $el->Add([
    'IBLOCK_ID'  => 5,
    'NAME'       => 'Товар',
    'PROPERTY_VALUES' => [
        'PHOTO' => [
            'VALUE' => \CFile::MakeFileArray('/path/image.jpg'),
            'DESCRIPTION' => 'Фото товара',
        ],
    ],
]);

// При обновлении — передаём ID существующего файла
$el->Update($elementId, [
    'PROPERTY_VALUES' => [
        'PHOTO' => ['VALUE' => $fileId],
    ],
]);

Удаление файла

// Удалить файл из базы и с диска
\CFile::Delete($fileId);

// Удалить только запись из базы (без файла)
\Bitrix\Main\Application::getInstance()->getConnection()->query(
    'DELETE FROM b_file WHERE ID = ' . (int) $fileId
);

Конвертация в WebP

// Проверить поддержку WebP
if (function_exists('imagewebp')) {
    $src = \$_SERVER['DOCUMENT_ROOT'] . $fileInfo['SRC'];
    $dst = str_replace('.jpg', '.webp', $src);
    
    $image = imagecreatefromjpeg($src);
    imagewebp($image, $dst, 85);
    imagedestroy($image);
    
    echo '/' . ltrim(str_replace(\$_SERVER['DOCUMENT_ROOT'], '', $dst), '/');
}

Итог

Всегда используйте CFile::SaveFile() и CFile::Delete() — они управляют записями в b_file. Прямое копирование файлов в /upload/ без регистрации в базе приводит к “потерянным” файлам которые невозможно найти или удалить через API.