Для начала создаем файл и подключаем в нем prolog_before.php и epilog_after.php, это нужно что бы нам были доступны методы API битрикс.
Выглядит это так:
<?
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
//тут будет наш будущий код
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
?>
Далее нам нужно определиться, каким образом мы хотим идентифицировать файл для скачивания:
а) это будет ID зарегистрированного файла в битрикс (например файл подгружен в свойство элемента инфоблока).
б) это просто файл лежащий на сервере, о котором битрикс ничего не знает и у которого нам известен только путь.
Создаем массив описывающий наш файл.
Для первого варианта (a), воспользуемся стандартным методом битрикс CFile::GetFileArray().
<?
//Формируем массив описывающий файл
//$id - это ID зарегистрированного файла в битрикс
$fileInfo = \CFile::GetFileArray($id);
?>
Обратите внимание, что в $fileInfo['ORIGINAL_NAME'] будет лежать оригинальное название файла, который вы подгружали средствами битрикс и при скачивании файла, браузер будет предлагать сохранить файл с этим именем. Поэтому при необходимости вы можете подставить свое название.
<?
$fileInfo = \CFile::GetFileArray($id);
//Если нужно, то изменяем имя файла с которым браузер будет предлагать его сохранить
$fileInfo['ORIGINAL_NAME'] = 'новое название файла для скачивания';
?>
Теперь рассмотрим второй вариант (б) и воспользуемся так же стандартным методом битрикс, только другим, CFile::MakeFileArray().
<?
//Получаем абсолютный путь до файла на сервере
//$filePath - это путь до файла относительно корня сайта, например '/images/image.png'
$filePathAbs = $_SERVER['DOCUMENT_ROOT'] . $filePath;
//Формируем массив описывающий файл, где подставляем $filePathAbs, абсолютный путь до файла
$fileInfo = \CFile::MakeFileArray($filePathAbs);
?>
В результате сформируется массив аналогичный $_FILES[имя] у которого в поле $fileInfo['name'] будет лежать название файла, которое так же можно переопределить.
С формированием массивов разобрались, теперь перейдем к методу для скачивания файла. Будем так же использовать стандартный метод битрикс CFile::ViewByUser(), именно он и отвечает за отдачу тела файла на скачивание.
Полная версия отдачи файла на скачивание для первого случая (а), когда у нас на входе есть ID зарегистрированного файла в 1С-Битрикс:
<?
//Подключаем пролог битрикс (что бы нам стало доступно API битрикс)
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
//Формируем специальный массив, описывающий файл для скачивания
$fileInfo = \CFile::GetFileArray($id);
//Если нужно, то изменяем имя файла с которым браузер будет предлагать его сохранить
$fileInfo['ORIGINAL_NAME'] = 'новое название файла для скачивания';
//Отдаем файл на скачивание
\CFile::ViewByUser(
$fileInfo,
['force_download' => true]
);
//Обязательно подключаем эпилог, иначе файл скачается с ошибкой
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
//После закрывающего тега PHP не должно быть символов, либо его можно вообще не закрывать
?>
Хотя структура массива для второго случая в корне отличается от структуры первого, она все равно подойдет. Метод понимает оба варианта.
Полная версия отдачи файла на скачивание для второго случая (б), когда у нас на входе есть путь до файла относительно корня сайта:
<?
//Подключаем пролог битрикс (что бы нам стало доступно API битрикс)
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
//Формируем специальный массив, описывающий файл для скачивания
$fileInfo = \CFile::MakeFileArray($_SERVER['DOCUMENT_ROOT'] . $filePath);
//Если нужно, то изменяем имя файла с которым браузер будет предлагать его сохранить
$fileInfo['name'] = 'новое название файла для скачивания';
//Отдаем файл на скачивание
\CFile::ViewByUser(
$fileInfo,
['force_download' => true]
);
//Обязательно подключаем эпилог, иначе файл скачается с ошибкой
require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
//После закрывающего тега PHP не должно быть символов, либо его можно вообще не закрывать
?>