W3docs

readfile()

Функция readfile() в PHP читает содержимое файла и выводит его в браузер. Это удобный способ отображения и скачивания файлов.

Введение

Функция PHP readfile() читает файл и записывает его напрямую в буфер вывода, возвращая количество прочитанных байт. Поскольку она передаёт файл в вывод напрямую, не сохраняя содержимое в PHP-переменной, это наиболее экономичный по памяти способ отправить файл в браузер — именно поэтому она является стандартным инструментом для скачивания файлов.

В этой главе рассматриваются синтаксис и параметры readfile(), возвращаемые значения, отличия от родственных функций file_get_contents() и fread(), а также безопасное использование для отображения и скачивания файлов.

Синтаксис

readfile(
    string $filename,
    bool $use_include_path = false,
    ?resource $context = null
): int|false
ПараметрОписание
$filenameПуть (или URL, если включён allow_url_fopen) к файлу для чтения и вывода.
$use_include_pathЕсли true, PHP также выполняет поиск файла в include_path. По умолчанию false.
$contextНеобязательный ресурс контекста потока (создаётся функцией stream_context_create()).

Возвращаемое значение: количество прочитанных байт или false при ошибке. Всегда проверяйте возвращаемое значение, а не игнорируйте его: отсутствующий файл вызывает предупреждение и всё равно отправляет частичный (зачастую пустой) ответ.

Как работает readfile()

При вызове readfile() PHP открывает файл, копирует его байты в буфер вывода частями и отправляет клиенту. Всё содержимое никогда не загружается в PHP-строку, поэтому потребление памяти остаётся низким даже для многогигабайтных файлов. Компромисс состоит в том, что у вас нет возможности преобразовать данные — на выходе получается побайтовая копия файла.

readfile() в сравнении с альтернативами

Выбор правильной функции имеет значение:

  • readfile() — потоковая передача файла напрямую в вывод. Лучший вариант для скачивания и передачи сырых файлов. Не возвращает строку, только количество отправленных байт.
  • file_get_contents() — читает весь файл в строку, чтобы вы могли изменять, искать или хранить его. Потребляет память, пропорциональную размеру файла.
  • fopen() + fread() — открывает дескриптор для точного позиционированного чтения; используется при необходимости читать управляемыми частями или перемещаться по файлу.
  • highlight_file() — выводит файл с подсветкой синтаксиса PHP (для отображения исходного кода).

Правило большого пальца: если вам нужно только отправить файл, используйте readfile(); если нужно обработать файл, читайте его в переменную.

Примеры

Пример 1: Отображение текстового файла

<?php

readfile('example.txt');

Это отправляет содержимое example.txt прямо в браузер. Если заголовок Content-Type не установлен, применяется значение по умолчанию сервера (обычно text/html).

Пример 2: Проверка возвращаемого значения

readfile() возвращает количество байт, что удобно для логирования или обработки ошибок:

<?php

$bytes = readfile('example.txt');

if ($bytes === false) {
    http_response_code(404);
    echo 'File not found.';
}

Пример 3: Принудительное скачивание

Чтобы браузер скачивал файл вместо его отображения, отправьте нужные заголовки до любого вывода, затем вызовите readfile():

<?php

$file = 'report.pdf';

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header('Content-Length: ' . filesize($file));

readfile($file);
exit;
  • Content-Type: application/octet-stream сообщает браузеру, что это двоичное скачивание.
  • Content-Disposition: attachment; filename="..." вызывает диалог «Сохранить как» и задаёт предлагаемое имя файла.
  • Content-Length позволяет браузеру отображать точный индикатор выполнения.

Заголовки передаются функцией header() и должны быть отправлены до того, как функция выведет какие-либо байты — иначе возникнет ошибка «headers already sent».

Распространённые ошибки

  • Никогда не передавайте в $filename несанированные данные от пользователя. Значение вроде ../../etc/passwd позволит злоумышленнику читать произвольные файлы (атака обхода пути). Ограничьте допустимые файлы белым списком или обработайте путь через basename() и ограничьте его известным каталогом.
  • Никакого вывода до заголовков. Даже случайный пробел или BOM перед <?php считается выводом и сломает Content-Disposition.
  • Очищайте буфер вывода для больших файлов. Если буферизация вывода включена, файл всё равно может буферизоваться в памяти. Вызовите ob_end_clean() (или flush()) перед readfile() при потоковой передаче очень больших файлов.
  • Чтение удалённых URL требует включения allow_url_fopen в php.ini.

Заключение

readfile() — основная функция PHP для отправки файла клиенту с минимальными накладными расходами на память: она передаёт байты прямо в вывод и возвращает количество отправленных байт. Используйте её для скачивания и передачи сырых файлов, применяйте совместно с header() для скачиваний, проверяйте имя файла во избежание атак обхода пути и обращайтесь к file_get_contents(), когда вам действительно нужно содержимое файла в переменной.

Практика

Практика
Что делает функция PHP readfile()?
Что делает функция PHP readfile()?
Was this page helpful?