Перейти к содержанию

Подсистема \Bitrix\Main\UI\Uploader принимает файлы от браузера. Она складывает их во временный каталог, проверяет размер и тип, а затем передает обработчику, который решает, что с файлом делать дальше: сохранить в файловое хранилище, привязать к элементу или отклонить.

Используйте подсистему, когда пользователь загружает файлы через форму: вложения к записи, документы к карточке, изображения в галерею. Файлы уходят на сервер по частям и отдельными запросами, поэтому большой файл не ограничен размером одного POST-запроса.

Подключить расширение

Интерфейс загрузки работает на JavaScript-расширении uploader. Компонент bitrix:main.file.input и класс FileInput подключают его сами, поэтому загружать расширение отдельно нужно только для своего интерфейса.

Если вы подключаете загрузку из PHP, загрузите расширение uploader.

\CJSCore::Init(['uploader']);

Расширение зарегистрировано в CJSCore, а не в модуле ui, поэтому метод \Bitrix\Main\UI\Extension::load() для него не используют.

Вместе с расширением подключаются его зависимости: ajax для запросов и dd для перетаскивания файлов. Загружать их отдельно не нужно.

Расширение создает в браузере глобальные объекты.

  • BX.Uploader — основной объект загрузки: очередь файлов, отправка фрагментов и обработка ответа сервера.

  • BX.UploaderQueue — очередь файлов, которые ждут отправки или отправляются сейчас.

  • BX.UploaderFile — один файл в очереди и его состояние.

  • BX.UploaderImage — файл-изображение. Объект наследует BX.UploaderFile и дополнительно готовит копии изображения в браузере, если они описаны параметром copies.

  • BX.UploaderUtils — вспомогательные функции: разбиение файла на фрагменты, чтение файла и список состояний загрузки.

После инициализации расширение вызывает событие onUploaderIsAlmostInited на объекте window. Подпишитесь на него, если нужно изменить параметры загрузки до ее старта.

Имена полей запроса задают параметры uploadInputName со значением bxu_files и uploadInputInfoName со значением bxu_info по умолчанию. Серверная часть читает файлы только из этих полей, поэтому меняйте имена вместе с серверным кодом.

Вывести поле загрузки

Готовый интерфейс выводит компонент bitrix:main.file.input. Он закрывает весь цикл сам: показывает выбранные файлы, отправляет их на сервер, сохраняет каждый файл через CFile::SaveFile() и подставляет в форму скрытое поле с идентификатором сохраненного файла. Собственный обработчик для этого писать не нужно.

Пример. Форма принимает один файл с расширением pdf и сохраняет его от имени модуля catalog.

<?php

$APPLICATION->IncludeComponent(
    'bitrix:main.file.input',
    '',
    [
        'INPUT_NAME' => 'DOCUMENT_FILE',
        'INPUT_VALUE' => [],
        'MODULE_ID' => 'catalog',
        'MULTIPLE' => 'N',
        'ALLOW_UPLOAD' => 'F',
        'ALLOW_UPLOAD_EXT' => 'pdf',
        'MAX_FILE_SIZE' => 10 * 1024 * 1024,
    ]
);

Основные параметры компонента.

|

|| Параметр | Описание || || INPUT_NAME | Имя поля формы, в котором приходят идентификаторы сохраненных файлов. Допустимы только латинские буквы, цифры и подчеркивание. Без этого параметра компонент выбрасывает ArgumentException || || INPUT_VALUE | Идентификаторы уже сохраненных файлов, которые нужно показать в поле. Массив или одно число || || MULTIPLE | Разрешает выбрать несколько файлов. По умолчанию Y || || ALLOW_UPLOAD | Что разрешено загружать: A — любые файлы, I — только изображения, F — только расширения из ALLOW_UPLOAD_EXT, N — загрузка запрещена и поле работает в режиме просмотра. По умолчанию A || || ALLOW_UPLOAD_EXT | Список разрешенных расширений через запятую. Работает вместе с ALLOW_UPLOAD со значением F. Если список пуст, компонент возвращается к значению A || || MAX_FILE_SIZE | Предельный размер одного файла в байтах. По умолчанию 0 — без ограничения || || MODULE_ID | Модуль, от имени которого файл попадает в файловое хранилище. От него зависит подкаталог в /upload/. По умолчанию main || || CONTROL_ID | Идентификатор поля, по которому подсистема отличает одно поле загрузки от другого на той же странице. Допустимы латинские буквы, цифры, дефис и подчеркивание. Если параметр не задан, компонент строит идентификатор из INPUT_NAME || || FORCE_MD5 | Дает файлу случайное имя в хранилище вместо исходного, даже если в настройках модуля main включено сохранение оригинальных имен. По умолчанию false || |#

Компонент вызывает два события модуля main после того, как файл сохранен в файловое хранилище: main.file.input.upload и main.file.input:onUploadAfter. Подпишитесь на них, если после сохранения нужно уменьшить изображение или записать свои данные.

Вывести поле в административном разделе

Класс \Bitrix\Main\UI\FileInput строит такое же поле для страниц настроек модуля и форм редактирования элементов. В отличие от компонента он не сохраняет файл сам: в форму приходят данные временного файла, а сохранение выполняет код страницы.

Настройки поля, источники файлов и разбор значений формы описаны в статье Поле выбора файлов FileInput.

Принять файлы своим обработчиком

Класс \Bitrix\Main\UI\Uploader\Uploader нужен, когда готовое поле не подходит: файл сохраняют не через CFile::SaveFile(), а своим кодом, либо к загрузке привязана дополнительная логика. Объект создают с параметрами и обработчиками, а затем вызывают метод checkPost() — он разбирает запрос браузера и выполняет ту операцию, которую браузер запросил.

Внимание

Класс CFileUploader устарел. Он продолжает работать как наследник \Bitrix\Main\UI\Uploader\Uploader и вызывает checkPost() прямо из конструктора. В новом коде используйте \Bitrix\Main\UI\Uploader\Uploader.

Пример. Объект принимает только изображения не больше 20 Мб, разрешает копию preview шириной 320 пикселей и хранит временные файлы в подкаталоге модуля catalog.

<?php

use Bitrix\Main\UI\Uploader\Uploader;

$uploader = new Uploader([
    'controlId' => 'documentScan',
    'allowUpload' => 'I',
    'uploadMaxFilesize' => 20 * 1024 * 1024,
    'copies' => [
        'preview' => [
            'width' => 320,
            'height' => 320,
        ],
    ],
    'storage' => [
        'moduleId' => 'catalog',
    ],
]);

Обработчики в этом примере не назначены, поэтому файл дойдет до временного каталога и останется там. Полный приемник с сохранением файла собран в разделе про сохранение файла в файловое хранилище.

Параметры конструктора.

|

|| Параметр | Описание || || controlId | Идентификатор поля загрузки. Он участвует в имени временного каталога, поэтому файлы двух разных полей не попадут в один каталог. По умолчанию fileUploader || || allowUpload | Что разрешено загружать: A — любые файлы, I — только изображения, F — только расширения из allowUploadExt. По умолчанию A || || allowUploadExt | Список разрешенных расширений через запятую. Работает вместе с allowUpload со значением F. По умолчанию пустая строка || || uploadMaxFilesize | Предельный размер одного файла в байтах. По умолчанию 0 — без ограничения || || copies | Копии изображения, которые разрешено принимать вместе с исходным файлом. Ключ массива — имя копии, значение — массив с ключами width и height. По умолчанию есть одна копия default с исходным файлом || || storage | Хранилище временных файлов: moduleId — модуль, в подкаталог которого попадают файлы, cloud — перенос файла в облако. По умолчанию moduleId равен main, а cloud — false || || events | Обработчики событий загрузки. Ключ — имя события, значение — вызываемый метод или функция || |#

Обработчики можно назначить и после создания объекта — методом setHandler(). Он принимает имя события и вызываемый метод, а возвращает сам объект, поэтому вызовы выстраиваются в цепочку.

$uploader
    ->setHandler('onFileIsUploaded', [$handler, 'handleFile'])
    ->setHandler('onPackageIsFinished', [$handler, 'finishUpload'])
;

Методы класса Uploader

Кроме приема файлов класс содержит несколько вспомогательных методов.

|

|| Метод | Описание || || checkPost($checkPost = true) | Разбирает запрос браузера и выполняет запрошенную операцию: прием, просмотр или удаление файла. Возвращает false, если в запросе нет служебных данных загрузки || || setHandler($name, $callback) | Назначает обработчик события загрузки и возвращает сам объект || || setControlId($controlId) | Меняет идентификатор поля загрузки после создания объекта || || getParam($key) | Возвращает значение параметра, с которым создан объект || || deleteFile($hash) | Удаляет временный файл и все его копии по хешу || || checkCanvases($hash, &$file, $canvases, $watermark) | Создает недостающие копии изображения и накладывает водяной знак || || getPaths($tmpName) | Статический метод. Возвращает массив с ключами tmp_name и tmp_url для файла, который уже лежит на диске сайта. Если файл не найден, возвращает false || |#

Выбрать точку приема

Браузер отправляет файлы на страницу, которая создает объект Uploader и вызывает checkPost(). Таких страниц две.

Своя страница подходит, когда загрузка встроена в компонент или в обработчик модуля. Создайте объект с нужными параметрами и вызовите checkPost() — метод сам разберет запрос и отдаст браузеру ответ в формате JSON.

Служебная страница /bitrix/tools/upload.php работает без своего кода на сервере. Она собирает объект Uploader из подписанных параметров, которые пришли в запросе, и требует двух условий: пользователь авторизован, а параметры подписаны методом \Bitrix\Main\UI\FileInputReceiver::sign(). Без подписи запрос отклоняется.

Подписывают тот же набор параметров, что передают в конструктор. Дополнительный параметр id задает, что страница вернет в форму: значение path — путь к временному файлу, значение hash — идентификатор загрузки.

<?php

use Bitrix\Main\UI\FileInputReceiver;

$signature = FileInputReceiver::sign([
    'id' => 'path',
    'allowUpload' => 'I',
    'allowUploadExt' => '',
]);

Метод checkPost() принимает необязательный аргумент. При значении true по умолчанию метод разбирает POST-запрос — по нему идет загрузка файлов. При значении false он разбирает GET-запрос: так подсистема отдает уже загруженный файл на просмотр.

Все режимы, кроме просмотра, проверяют идентификатор сессии. Если проверка не прошла, метод выбрасывает AccessDeniedException с текстом Bad sessid., поэтому JavaScript-код обязан отправлять параметр sessid вместе с файлами.

Обработать события загрузки

Вмешаться в загрузку можно только обработчиком. Подсистема вызывает обработчики в двух масштабах: события пакета относятся ко всему набору файлов в запросе, события файла — к каждому файлу отдельно.

Загрузка идет несколькими запросами: браузер отправляет файлы частями, и на каждый запрос подсистема создает новый пакет. Поэтому у событий начала есть парные события продолжения — они срабатывают на втором и последующих запросах той же загрузки.

|

|| Событие | Когда срабатывает | Аргументы обработчика || || onUploadIsStarted | При первом запросе загрузки для этого поля | &$log, &$cidLog, &$post, &$files, &$error || || onUploadIsContinued | При следующих запросах той же загрузки | &$log, &$cidLog, &$post, &$files, &$error || || onPackageIsStarted | При начале обработки нового пакета файлов | &$log, &$cidLog, &$post, &$files, &$error || || onPackageIsContinued | При продолжении обработки уже начатого пакета | &$log, &$cidLog, &$post, &$files, &$error || || onFileIsStarted | При появлении нового файла в пакете | $hash, &$data, &$error || || onFileIsContinued | При появлении файла, часть которого уже загружена | $hash, &$data, &$error || || onFileIsUploaded | При полной загрузке файла во временный каталог | $hash, &$fileArray, &$log, &$cidLog, &$error || || onPackageIsFinished | При загрузке всех заявленных файлов пакета | &$log, &$cidLog, &$post, &$response, &$error || |#

Обработчик прерывает загрузку, если вернет false. Текст причины он записывает в аргумент $error, который передается по ссылке. Дальше реакция зависит от события. На событии пакета подсистема выбрасывает NotImplementedException с этим текстом. На событии файла она записывает файлу ошибку с кодом BXU350.1 и продолжает обрабатывать остальные файлы пакета.

Сохранить файл в файловое хранилище

Событие onFileIsUploaded — точка, в которой временный файл становится постоянным. К этому моменту файл полностью лежит во временном каталоге, проверки размера и типа пройдены, а все заявленные копии приняты.

Временный каталог подсистема создает внутри каталога загрузки, обычно это /upload/. Файлы в нем живут 12 часов и удаляются по расписанию, поэтому загруженный файл нужно сохранить в файловое хранилище продукта. С этим хранилищем работают метод CFile::SaveFile() и все поля типа «файл».

Аргумент $fileArray содержит данные файла. Ключи name, type и size описывают файл целиком, а вложенный массив files — его копии. У каждой копии есть ключи tmp_name с полным путем к временному файлу, url со ссылкой для просмотра, size и type. Копия default есть всегда.

Пример. Готовая страница-приемник: обработчик сохраняет копию default в файловое хранилище, удаляет временный файл и возвращает браузеру идентификатор сохраненного файла.

<?php

use Bitrix\Main\UI\Uploader\Uploader;

class DocumentUploadHandler
{
    private ?Uploader $uploader = null;

    public function setUploader(Uploader $uploader): void
    {
        $this->uploader = $uploader;
    }

    public function handleFile($hash, &$fileArray, &$log, &$cidLog, &$error)
    {
        $fileId = \CFile::SaveFile($fileArray['files']['default'], 'catalog');
        if ($fileId <= 0)
        {
            $error = 'Файл не сохранен';

            return false;
        }

        $this->uploader->deleteFile($hash);

        $fileArray['file_id'] = $fileId;

        return true;
    }
}

$handler = new DocumentUploadHandler();

$uploader = new Uploader([
    'controlId' => 'documentScan',
    'allowUpload' => 'I',
    'storage' => [
        'moduleId' => 'catalog',
    ],
    'events' => [
        'onFileIsUploaded' => [$handler, 'handleFile'],
    ],
]);

$handler->setUploader($uploader);

$uploader->checkPost();

Метод deleteFile() убирает временный файл и его копии сразу после сохранения. Без этого вызова файл останется во временном каталоге до очистки по расписанию и будет занимать место дважды.

Все, что обработчик добавит в $fileArray, подсистема вернет браузеру в ответе. Так идентификатор сохраненного файла попадает в форму.

Ограничить размер и типы файлов

Разрешенный размер и тип файла задают параметры uploadMaxFilesize, allowUpload и allowUploadExt. Подсистема проверяет их на сервере — до того, как файл попадет в обработчик события, и независимо от того, что проверил браузер.

Размер сверяется первым. Файл сверх заданного предела получает ошибку с кодом BXU347.3, остальные файлы пакета загружаются дальше.

Тип файла проверяет метод CFile::CheckFile(). Для изображений он сверяет файл со списком графических расширений продукта, для режима со списком расширений — с тем, что перечислено в allowUploadExt. Файл, который не прошел проверку, до обработчика события не доходит.

Внимание

Параметры uploadFileWidth и uploadFileHeight ограничивают размеры изображения только в браузере. На сервере таких проверок нет, поэтому запрос в обход интерфейса их не заметит. Если предельные размеры изображения важны, проверьте их своим кодом в обработчике onFileIsUploaded.

Ограничения самого PHP действуют независимо от параметров подсистемы. Значения upload_max_filesize, post_max_size и max_file_uploads подсистема передает в браузер, чтобы он не отправлял заведомо непроходимый запрос.

Создать копии файла

Уменьшенный вариант изображения приходит на сервер вместе с исходным файлом. Уменьшает изображение браузер: он рисует его на элементе canvas по заданным размерам и отправляет результат отдельным файлом. Сервер по параметру copies разрешает имена копий и отклоняет копию с именем не из списка.

Размеры копии задают ключи width и height в пикселях: изображение вписывается в них с сохранением пропорций. Копия default есть всегда и хранит исходный файл. Имя копии попадает в массив files обработчика события и в имя временного файла на диске.

Пример. Поле разрешает две копии: preview для карточки и thumbnail для списка.

$params['copies'] = [
    'preview' => [
        'width' => 320,
        'height' => 320,
    ],
    'thumbnail' => [
        'width' => 90,
        'height' => 90,
    ],
];

Метод checkCanvases() создает копии на сервере — тогда, когда браузер их не прислал. Он принимает хеш файла, массив данных файла по ссылке, описание копий и параметры водяного знака. Копию, которой еще нет в массиве files, метод делает из копии default и вписывает в заданные размеры с сохранением пропорций. Если передать параметры водяного знака, метод наложит его и на копию default.

Пример. Обработчик добавляет копию medium шириной 600 пикселей уже после того, как файл загружен.

$fileArray = $uploader->checkCanvases(
    $hash,
    $fileArray,
    [
        'medium' => [
            'width' => 600,
            'height' => 600,
        ],
    ]
);

Выбрать хранилище для файлов

Место для временных файлов задает параметр storage.

Настройка moduleId задает модуль, в подкаталог которого попадают файлы. Подсистема очищает значение от посторонних символов и по умолчанию использует main. Указывайте свой модуль, если загрузка относится к нему: так временные файлы разных механизмов не смешиваются.

Настройка cloud со значением true переносит загруженный файл в облачное хранилище. Перенос включается при двух условиях: установлен модуль clouds и значение upload_max_filesize в настройках PHP не меньше 5 Мб. Если хотя бы одно условие не выполнено, подсистема сохраняет файл на диск и продолжает загрузку без сообщения об ошибке.

Пример. Временные файлы попадают в подкаталог модуля catalog, а загруженный файл переносится в облако.

$params['storage'] = [
    'moduleId' => 'catalog',
    'cloud' => true,
];

При переносе в облако подсистема добавляет копии ключ bucketId с идентификатором бакета, а для изображения определяет ширину и высоту.

Загружать файлы по частям

Браузер делит большой файл на фрагменты и отправляет их отдельными запросами. Подсистема собирает фрагменты обратно и вызывает onFileIsUploaded только после того, как получит их все.

Имя фрагмента несет всю нужную для сборки информацию и выглядит как <копия>.ch<номер>.<смещение>.chs<всего>:

  • <копия> — имя копии, к которой относится фрагмент,

  • ch<номер> — порядковый номер фрагмента,

  • <смещение> — позиция фрагмента от начала файла в байтах,

  • chs<всего> — общее число фрагментов.

Подсистема разбирает имя, открывает целевой файл, блокирует его и записывает фрагмент с нужного смещения. Порядок фрагментов значения не имеет. Пока не пришел последний фрагмент, копия остается в состоянии inprogress, и событие загрузки файла не срабатывает.

Собственного кода загрузка по частям не требует — ее ведет JavaScript-расширение. Помнить о ней нужно при написании обработчиков: onFileIsStarted срабатывает один раз, а onFileIsContinued — на каждом следующем запросе того же файла.

Один запрос подсистема обрабатывает не дольше, чем три четверти от значения max_execution_time. Файлы, на которые времени не хватило, переходят в следующий запрос.

Загрузить файл по ссылке

Кроме бинарных данных подсистема принимает ссылку на файл. Так работает выбор файла из медиабиблиотеки или из облачного хранилища: браузер отправляет не содержимое, а адрес, и файл забирает сервер.

Подсистема различает два вида ссылок.

  • Ссылка без домена указывает на файл внутри сайта. Подсистема собирает данные файла методом CFile::MakeFileArray() и копирует его во временный каталог.

  • Ссылка с доменом указывает на внешний файл. Подсистема отправляет HTTP-запрос методом HEAD, берет размер и тип из заголовков ответа, а затем скачивает файл. Ответ со статусом, отличным от 200, прерывает прием файла ошибкой с кодом BXU347.2.

Оба вида ссылок проходят те же проверки, что и обычный файл. Подсистема сначала узнает размер и тип, а затем сверяет их с параметрами загрузки.

Метод getPaths() готовит данные для такого сценария на стороне сервера. Он принимает путь к файлу, который уже лежит на диске сайта, и возвращает массив с ключами tmp_name и tmp_url.

Пример. Код получает пару путей для файла на диске сайта и передает ссылку в описание файла.

<?php

use Bitrix\Main\UI\Uploader\Uploader;

$paths = Uploader::getPaths('/upload/tmp/report.pdf');
if (is_array($paths))
{
    $file['tmp_url'] = $paths['tmp_url'];
}

Показать и удалить загруженный файл

Пока файл лежит во временном каталоге, его нельзя отдать по прямой ссылке: каталог закрыт от прямого доступа. Подсистема сама отдает файл и сама его удаляет — по режиму, который приходит в запросе.

|

|| Режим | Что делает || || upload | Принимает файлы. Требует POST-запроса и проверки идентификатора сессии || || view | Отдает загруженный файл браузеру по хешу. Идентификатор сессии не проверяет, но отдает только файл, привязанный к полю загрузки в сессии этого пользователя || || delete | Удаляет загруженный файл и его копии по хешу. Требует проверки идентификатора сессии || |#

Метод checkPost() отклоняет любое другое значение режима исключением ArgumentOutOfRangeException.

Ссылку для просмотра подсистема формирует сама и записывает в ключ url каждой копии. Отдельно строить адрес не нужно.

Большой файл отдается по частям: подсистема обрабатывает заголовок Range и возвращает запрошенный отрезок. Повторный запрос того же файла закрывается заголовком ETag без передачи содержимого.

Удалить файл из своего кода можно и до конца загрузки — методом deleteFile(). Так делает обработчик, который уже сохранил файл в файловое хранилище.

Проверить файл перед сохранением

Класс \Bitrix\Main\UI\FileInputUtility связывает поле загрузки, файлы и сессию пользователя. С его помощью серверный код проверяет, относится ли присланный файл к этой форме.

Поле загрузки регистрируется в сессии и получает идентификатор CID. Каждый загруженный файл подсистема привязывает к этому идентификатору. Когда форма отправлена, серверный код проверяет присланные идентификаторы файлов по списку из сессии и отбрасывает чужие.

Объект класса получают методом instance().

|

|| Метод | Описание || || registerControl($cid, $controlId) | Регистрирует поле загрузки в сессии и возвращает его идентификатор CID. Если передать CID пустым, метод создаст новый || || registerFile($cid, $fileId) | Привязывает файл к полю загрузки. Вызывайте после того, как файл сохранен || || unRegisterFile($cid, $fileId) | Снимает привязку файла к полю. Возвращает true, если файл был привязан || || checkFile($cid, $fileId) | Проверяет, привязан ли файл к полю. Возвращает true или false || || checkFiles($controlId, $files) | Оставляет в массиве идентификаторов только те файлы, которые привязаны к полю. Остальные удаляет || || checkDeletedFiles($controlId) | Удаляет файлы, отмеченные пользователем к удалению, и возвращает список удаленных идентификаторов || |#

Пример. Код формы отбрасывает идентификаторы файлов, которые не загружались через это поле, и только потом записывает их в свои данные.

<?php

use Bitrix\Main\Context;
use Bitrix\Main\UI\FileInputUtility;

$request = Context::getCurrent()->getRequest();

$fileIds = FileInputUtility::instance()->checkFiles(
    'documentScan',
    $request->getPost('DOCUMENT_FILE') ?? []
);

Без этой проверки форма примет любой идентификатор файла, который пришел в запросе, включая идентификатор чужого файла.

Разобрать ошибки загрузки

Подсистема разделяет два вида сбоев. Нарушение условий запроса прерывает работу исключением, а проблема с конкретным файлом становится ошибкой этого файла и не мешает остальным.

Метод checkPost() перехватывает исключения сам и отдает браузеру ответ со статусом error и текстом ошибки. Поэтому исключения видны в ответе загрузчика, а не в журнале ошибок PHP.

|

|| Исключение | Причина || || ArgumentOutOfRangeException | В запросе указан режим, которого нет. Допустимы upload, view и delete || || AccessDeniedException | Не прошла проверка идентификатора сессии в режиме загрузки или удаления || || NotImplementedException | Не создан временный каталог, запрос пришел не методом POST либо обработчик события пакета вернул false || || ArgumentNullException | В запросе нет обязательного параметра: пути, идентификатора поля или номера пакета || || ArgumentException | Значение параметра не проходит проверку формата: число файлов не целое, номер пакета задан не по шаблону, идентификатор поля содержит косую черту || |#

Ошибки файла приходят в ответе браузеру вместе со статусом error для этого файла. Код ошибки указывает на этап, где сбой произошел.

|

|| Код | Причина || || BXU346.2 | Не удалось начать передачу файла в облачное хранилище || || BXU346.3 | Не удалось прочитать временный файл перед передачей в облако || || BXU346.4 | Передача части файла в облако не прошла за отведенное число попыток || || BXU346.5 | Не удалось завершить передачу файла в облако || || BXU347.1 | Не создан временный каталог для загрузки || || BXU347.2 | Файл по ссылке недоступен: ответ пришел со статусом, отличным от 200 || || BXU347.2.1 | Файл по ссылке не скачался во временный каталог || || BXU347.2.2 | Временный файл не найден на диске || || BXU347.2.4 | Файл не перемещен из временного каталога PHP || || BXU347.2.7 | Путь к файлу ведет вне разрешенного каталога загрузки || || BXU347.2.8 | Бакет облачного хранилища не найден || || BXU347.2.9<n> | Ошибка PHP при приеме файла. Цифра в конце совпадает с кодом UPLOAD_ERR_*: например, BXU347.2.91 — файл больше значения upload_max_filesize || || BXU347.3 | Файл не прошел проверку размера, типа или расширения || || BXU349.1 | Не создан файл для сборки фрагментов || || BXU349.2 | Не удалось прочитать фрагмент файла || || BXU349.3 | Не удалось открыть фрагмент файла || || BXU349.100 | Собираемый файл заблокирован другим процессом || || BXU350.0 | Данные файла не восстановились из журнала загрузки || || BXU350.1 | Обработчик события вернул false. Текст причины берется из аргумента $error || || BXU351.01 | Журнал загрузки прочитан, но имеет неверную структуру || || BXU351.02 | Журнал загрузки не сохранен на диск || || BXU351.03 | Журнал загрузки не удален || |#

Подробный разбор сбоев попадает в журнал ошибок PHP, если в настройках модуля main включен параметр uploaderLog. По умолчанию запись выключена.

Связанные материалы