Файлы из кода - сохранение, уменьшенные копии, удаление
Кладём файл в хранилище платформы, показываем его и убираем за собой, не оставляя за спиной каталог загрузок на десятки гигабайт.
Решение
Сохраняем файл в хранилище:
$fileId = CFile::SaveFile(CFile::MakeFileArray($tmpPath), 'vendor.shop');// второй аргумент - подкаталог хранения, по нему потом видно, чьи это файлы$element->Update($id, ['PROPERTY_VALUES' => ['DOC' => $fileId]]);// в поле или свойство кладут номер файла, а не путь к немуХранилище возвращает номер файла, и именно он живёт в полях и свойствах. Платформа сама решает, в какой каталог его положить, и это освобождает вас от раскладки файлов по подкаталогам.
Собираем путь для вывода:
$path = CFile::GetPath($fileId); // путь для ссылки на странице$info = CFile::GetFileArray($fileId); // и всё остальное: имя, размер, тип// пустой ответ означает, что запись о файле уже удалена из таблицыprintf('<a href="%s">%s</a>', $path, htmlspecialchars($info['ORIGINAL_NAME']));Путь собирают по номеру в момент вывода, а не хранят в базе. На кластере или после смены каталога хранения жёстко записанный путь ломается первым, и чинить его приходится по всему проекту сразу.
Готовим уменьшенную копию:
$thumb = CFile::ResizeImageGet( $fileId, ['width' => 300, 'height' => 300], BX_RESIZE_IMAGE_PROPORTIONAL, true // копия создаётся при первом обращении и потом переиспользуется);echo '<img src="' . $thumb['src'] . '" loading="lazy">';Копия нужного размера создаётся при первом обращении к ней. Десяток разных размеров на одну картинку - это десяток файлов на диске, поэтому набор размеров стоит держать коротким и одинаковым по всему сайту.
Убираем файл за собой:
CFile::Delete($fileId);// файлы полей и свойств платформа убирает вместе с элементом сама// а вот сохранённое своим кодом удаляет только ваш кодФайл, сохранённый вашим кодом, удаляет тоже ваш код. Иначе каталог загрузок растёт годами, и однажды резервная копия перестаёт помещаться туда, куда её складывают.
Загруженное посетителем проверяют до сохранения, а не после. Каталог загрузок доступен снаружи, и попавший в него исполняемый файл превращается в чужой вход на сайт.
Файлы для служебных надобностей стоит держать вне каталога загрузок. Выгрузки с персональными данными и журналы обмена там доступны любому, кто угадает имя.
Имя файла от посетителя не переносят на диск как есть. Платформа приводит его к безопасному виду, а вот свой код с прямой записью файла эту работу пропускает.
Типичные проблемы
Файл сохраняется, а на странице не виден.
В поле записан путь вместо номера файла из хранилища. Путь собирают по номеру уже в момент вывода.
Сохранение падает без внятной ошибки.
У каталога загрузок нет прав на запись для владельца процесса. Права на этот каталог проверяют самым первым делом при любом разборе.
Каталог загрузок вырос до десятков гигабайт.
Файлы сохранялись своим кодом и никогда не удалялись. Удаление такого файла - обязанность того же кода.
Картинки на витрине занимают гигабайты копий.
Уменьшенные копии одной и той же картинки делаются в десятке разных размеров. Набор размеров держат коротким и общим для всего сайта, а не для страницы.
В каталоге загрузок оказался чужой скрипт.
Тип загружаемого файла не проверялся вашим кодом перед его сохранением на диск. Проверку делают до записи, а не после неё.
Частые вопросы
Можно ли хранить файлы вне хранилища платформы?
Да, если это служебные файлы и вы сами следите за их чисткой. Пользовательские удобнее держать в хранилище.
Как отдать файл только авторизованным?
Хранить его вне доступного снаружи каталога и отдавать скриптом с проверкой прав. Ссылка на каталог загрузок такой проверки не даёт.
Что делать со старыми уменьшенными копиями?
Чистить их вместе со сменой набора размеров. Иначе на диске остаются копии, которые никто не запрашивает.
Как перенести файлы между стендами?
Отдельно от базы и отдельно от кода. Каталог загрузок в репозиторий не кладут: он растёт непредсказуемо.
Смежное
-
Файлы в коде - оглавление подтемы
-
Файл не загружается: пределы, права, типы, веб-сервер - разбор, когда загрузка не проходит
-
Картинки товара: загрузка, размеры и вывод галереи - то же самое в каталоге
-
Права на файлы и папки: файловая система и права структуры - почему файл не сохраняется
-
Папка загрузок растёт: дубли картинок и лишние файлы - что делать с накопленным
-
Ядро D7 - устройство ядра целиком
-
Отдача файла с проверкой прав: закрытые каталоги, заголовки, ссылки - файлы не для всех
-
Данные от посетителя: экранирование, проверка, сеанс - проверка файла до сохранения
-
Загрузка файла с формы: приём, проверки, прогресс, хранение - откуда файл попадает в хранилище
-
Файлы платформы изнутри: таблица, каталоги, копии, удаление - как устроено хранилище под этими вызовами
-
Картинки не отображаются: разбор причин - что ломает ссылку на сохранённый файл