Как получить файл в PHP: основные функции и их применение

Раздел: Программирование на PHP -> Работа с файловой системой

Способы получения файла в PHP

Основное решение: file_get_contents

Наиболее эффективный способ прочитать содержимое файла в строку - использовать функцию file_get_contents(). Она подходит для небольших и средних файлов, так как загружает всё содержимое в память.


$content = file_get_contents('example.txt');
echo $content;
  

Если файл не найден, функция вернёт false и вызовет предупреждение. Рекомендуется проверять результат:


if (($content = file_get_contents('example.txt')) !== false) {
    echo 'Содержимое: ' . $content;
} else {
    echo 'Не удалось прочитать файл';
}
  

Проблемы: большие файлы могут превысить лимит памяти (memory_limit). Для файлов размером более нескольких мегабайт лучше использовать потоковое чтение.

Типичные ошибки: неправильный путь (относительный/абсолютный), отсутствие прав на чтение. Решение: проверять существование файла функцией file_exists() или is_readable().

Цель: быстрое получение всего содержимого текстового файла, конфигураций, шаблонов.

Как читать файл построчно или по частям, чтобы не перегружать память?

Используйте fopen() в паре с fgets() или fread(). Это позволяет обрабатывать файл любого размера.


$handle = fopen('large.log', 'r');
if ($handle) {
    while (($line = fgets($handle)) !== false) {
        echo $line;
    }
    fclose($handle);
} else {
    echo 'Ошибка открытия файла';
}
  

Проблемы: забыли закрыть файл (fclose) - утечка ресурсов. Решение: использовать блок try-finally или ресурс оборачивать в класс, реализующий деструктор.

Ошибки: неверный режим ('r' вместо 'rb' для бинарных файлов на Windows может повредить данные).

Цель: чтение логов, CSV-файлов, любых данных, где не требуется весь файл в памяти.

Как получить файл целиком в виде массива строк?

Функция file() возвращает массив, каждый элемент - строка файла (с сохранением символа конца строки).


$lines = file('data.txt');
foreach ($lines as $i => $line) {
    echo 'Строка ' . ($i+1) . ': ' . $line;
}
  

Аналогично file_get_contents, загружает весь файл в память.

Проблемы: для очень больших файлов - переполнение памяти. Решение: использовать fopen+fgets для потоковой обработки.

Типичная ошибка: не удаляются символы новой строки. Можно использовать array_map('trim', $lines).

Цель: простой разбор списков, конфигураций, где строки - самостоятельные записи.

Как сразу вывести содержимое файла в браузер без сохранения в переменную?

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


$filename = 'report.pdf';
if (file_exists($filename)) {
    header('Content-Type: application/pdf');
    header('Content-Disposition: inline; filename="' . basename($filename) . '"');
    readfile($filename);
    exit;
} else {
    http_response_code(404);
    echo 'Файл не найден';
}
  

Проблемы: отсутствие прав, выход за лимит времени выполнения для больших файлов. Решение: использовать set_time_limit(0) и flush.

Ошибки: вывод случайного содержимого до header (пробелы, BOM).

Цель: прямая передача файла клиенту, минимизация использования памяти.

Как получить файл по URL (удалённый ресурс)?

Включите allow_url_fopen и используйте file_get_contents() с URL. Для более тонкого управления используйте cURL.


$url = 'https://example.com/data.json';
$json = file_get_contents($url);
if ($json !== false) {
    $data = json_decode($json, true);
    print_r($data);
} else {
    echo 'Ошибка получения данных';
}
  

cURL вариант:


$ch = curl_init('https://example.com/data.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode == 200) {
    echo $response;
} else {
    echo 'Ошибка HTTP: ' . $httpCode;
}
  

Проблемы: allow_url_fopen отключён на хостинге, время ожидания, сертификаты SSL. Решение: использовать cURL с установкой опций timeout, SSL_VERIFYPEER.

Ошибки: не обработаны редиректы, не проверен HTTP-статус.

Цель: получение внешних данных, API-запросы, загрузка файлов по HTTP/HTTPS.

Как получить загруженный пользователем файл (из формы)?

После отправки формы с enctype='multipart/form-data' файл доступен в массиве $_FILES. Для получения его содержимого используйте file_get_contents() из временного расположения.


if (isset($_FILES['uploaded_file']) && $_FILES['uploaded_file']['error'] === UPLOAD_ERR_OK) {
    $tmpPath = $_FILES['uploaded_file']['tmp_name'];
    $content = file_get_contents($tmpPath);
    echo 'Размер: ' . strlen($content) . ' байт';
} else {
    echo 'Ошибка загрузки';
}
  

Проблемы: превышение лимита upload_max_filesize, ошибки при частичной загрузке. Решение: проверять код ошибки и валидировать тип/размер.

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

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

Расширенные примеры получения файлов

1. Потоковое чтение большого файла с прогрессом

Пример чтения файла размером 100 МБ блоками по 1 МБ с выводом прогресса.

Пример

$filename = 'large_file.bin';
$chunkSize = 1024 * 1024; // 1 MB
$handle = fopen($filename, 'rb');
if ($handle) {
    $size = filesize($filename);
    $read = 0;
    while (!feof($handle)) {
        $chunk = fread($handle, $chunkSize);
        if ($chunk === false) {
            echo 'Ошибка чтения';
            break;
        }
        $read += strlen($chunk);
        // Обработка chunk (например, запись в другой файл)
        $progress = round($read / $size * 100);
        echo "Прочитано $progress%\n";
        // Сброс буфера для веб-сценариев
        flush();
    }
    fclose($handle);
} else {
    echo 'Не удалось открыть файл';
}
Прочитано 10%
Прочитано 20%
...
Прочитано 100%

2. Получение удалённого файла с авторизацией и таймаутом

Использование cURL для загрузки защищённого ресурса с Basic HTTP аутентификацией.

Пример

$url = 'https://api.example.com/private/report.csv';
$username = 'user';
$password = 'pass';
$timeout = 30;

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => $timeout,
    CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
    CURLOPT_USERPWD => "$username:$password",
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_CAINFO => '/path/to/cacert.pem'
]);

$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

if ($httpCode === 200 && $result !== false) {
    file_put_contents('report.csv', $result);
    echo 'Файл скачан успешно, размер: ' . strlen($result) . ' байт';
} else {
    echo 'Ошибка: HTTP ' . $httpCode . ' - ' . $error;
}
Файл скачан успешно, размер: 245678 байт

3. Чтение файла в обратном порядке (последние N строк)

Реализация получения последних 10 строк большого лога без чтения всего файла.

Пример

function tail($filename, $lines = 10) {
    $handle = fopen($filename, 'r');
    if (!$handle) return false;
    
    fseek($handle, 0, SEEK_END);
    $pos = ftell($handle);
    $data = '';
    $count = 0;
    
    while ($pos > 0 && $count < $lines) {
        $pos--;
        fseek($handle, $pos);
        $char = fgetc($handle);
        if ($char === "\n" && $pos < ftell($handle) - 1) {
            $count++;
        }
        $data = $char . $data;
    }
    fclose($handle);
    // обрезаем возможный лишний символ в начале
    return substr($data, 1);
}

echo tail('error.log', 5);
[2025-03-10 12:00:01] ERROR: DB connection failed
[2025-03-10 12:00:02] WARNING: Retry attempt 1
[2025-03-10 12:00:05] ERROR: DB connection failed again
[2025-03-10 12:00:10] ERROR: Giving up
[2025-03-10 12:00:12] INFO: Service restarted

4. Получение файла через SSH (SFTP) с помощью phpseclib

Для доступа к удалённому файлу по протоколу SFTP используйте библиотеку phpseclib.

Пример

require 'vendor/autoload.php';

use phpseclib3\Net\SFTP;

$sftp = new SFTP('192.168.1.100');
if (!$sftp->login('username', 'password')) {
    die('Ошибка аутентификации');
}

$remoteFile = '/var/log/application.log';
$content = $sftp->get($remoteFile);
if ($content !== false) {
    echo 'Получено ' . strlen($content) . ' байт';
} else {
    echo 'Не удалось прочитать файл';
}
Получено 12893 байт

5. Чтение файла с условной распаковкой (gzip)

Если файл сжат gzip, можно прочитать его и распаковать на лету.

Пример

$gzFile = 'data.csv.gz';
$handle = gzopen($gzFile, 'r');
if ($handle) {
    while (!gzeof($handle)) {
        $line = gzgets($handle);
        echo $line;
    }
    gzclose($handle);
} else {
    echo 'Ошибка открытия gz-файла';
}
id,name,email
1,Иван,ivan@example.com
2,Петр,petr@example.com

Получение файла в PHP - comments

En
Php получить файл (php)