Fread: примеры (PHP)

Использование PHP функции fread для работы с данными
Раздел: Работа с файлами
fread(resource $stream, int $length): string|false
Описание и параметры функции fread

Функция fread в языке PHP предназначена для чтения данных из файла или другого потока в бинарно-безопасном режиме. Её применение актуально при работе с бинарными файлами, такими как изображения, или когда требуется контролировать размер считываемого блока данных, например, при чтении больших файлов частями.

Сигнатура функции: fread(resource $stream, int $length): string|false.

Функция принимает два аргумента:

  1. $stream (resource) — ресурс (указатель) файла, полученный с помощью функций fopen(), fsockopen() или popen(). Этот ресурс должен быть открыт для чтения.
  2. $length (int) — максимальное количество байт для чтения. Чтение останавливается после прочтения указанного количества байт, при достижении конца файла (EOF) или в случае ошибки (например, при разрыве сетевого соединения для сокетов).

Функция возвращает прочитанную строку или false в случае ошибки.

Простые примеры использования fread
Чтение всего содержимого файла
<?php
$handle = fopen('example.txt', 'rb');
if ($handle) {
    $content = fread($handle, filesize('example.txt'));
    fclose($handle);
    echo $content;
}
?>
Содержимое файла example.txt
Чтение файла по частям (блоками)
<?php
$handle = fopen('large_file.bin', 'rb');
if ($handle) {
    while (!feof($handle)) {
        $chunk = fread($handle, 8192); // Чтение блоками по 8 КБ
        // Обработка блока данных $chunk
        echo strlen($chunk) . ' байт прочитано\n';
    }
    fclose($handle);
}
?>
8192 байт прочитано
8192 байт прочитано
...
1200 байт прочитано (последний блок)
Чтение из сетевого сокета
<?php
$fp = fsockopen('example.com', 80, $errno, $errstr, 30);
if ($fp) {
    $request = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n";
    fwrite($fp, $request);
    $responseHeader = '';
    // Чтение ответа построчно до пустой строки (конец заголовков)
    while (!feof($fp)) {
        $line = fread($fp, 1024);
        $responseHeader .= $line;
        if (strpos($responseHeader, "\r\n\r\n") !== false) {
            break;
        }
    }
    echo $responseHeader;
    fclose($fp);
}
?>
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
... (остальные заголовки)
Похожие функции в PHP
  • file_get_contents() — считывает весь файл в строку. Используется для простого чтения небольших файлов целиком. Не требует явного открытия и закрытия файла.
    $content = file_get_contents('file.txt');
  • fgets() — читает файл построчно. Удобна для обработки текстовых файлов, где важны границы строк.
    while ($line = fgets($handle)) { echo $line; }
  • stream_get_contents() — считывает оставшуюся часть потока в строку. Может быть аналогом fread($handle, filesize(...)), но работает с любым потоком и позволяет указывать максимальную длину и смещение.
    $content = stream_get_contents($handle);
  • fgetc() — читает один символ из файла. Используется для посимвольной обработки.

Выбор функции зависит от задачи: fread применяется для бинарно-безопасного чтения данных заданного размера, особенно для бинарных файлов или потоковых данных. file_get_contents предпочтительнее для простого чтения текстовых файлов целиком. fgets лучше подходит для построчного анализа.

Аналоги функции в других языках

Fread в Python

Метод read(size) у файловых объектов. Аналогичен fread, но интегрирован в объект файла.

with open('example.txt', 'rb') as f:
    data = f.read(1024)  # Чтение 1024 байт
    print(data)
b'Содержимое файла...'
JavaScript (Node.js)

Модуль fs предлагает несколько методов: fs.readSync(fd, buffer, offset, length, position) для синхронного чтения в буфер и fs.readFile для чтения всего файла.

const fs = require('fs');
const fd = fs.openSync('file.txt', 'r');
const buffer = Buffer.alloc(1024);
const bytesRead = fs.readSync(fd, buffer, 0, 1024, null);
console.log(buffer.toString('utf8', 0, bytesRead));
fs.closeSync(fd);
Содержимое файла...

Fread в MySQL

Функция LOAD_FILE() считывает весь файл и возвращает его содержимое как строку. Работает на уровне СУБД, а не в языке приложения.

SELECT LOAD_FILE('/tmp/data.txt') AS file_content;
+-------------------+
| file_content      |
+-------------------+
| Текст из файла    |
+-------------------+

Основное отличие от PHP в том, что в Python и JS работа с файлами чаще объектно-ориентированная, а fread в PHP использует ресурсы. Кроме того, в PHP больше акцента на бинарную безопасность по умолчанию.

Распространенные ошибки
Передача некорректного ресурса
<?php
$data = fread(false, 10); // Предупреждение и возврат false
?>
Warning: fread() expects parameter 1 to be resource, bool given
Чтение из директории вместо файла
<?php
$handle = fopen('/tmp', 'r');
$data = fread($handle, 100); // Чтение невозможно
?>
Warning: fread(): read of 8192 bytes failed with errno=21 Is a directory
Игнорирование проверки на конец файла (feof)

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

<?php
$handle = fopen('empty.txt', 'r');
$content = fread($handle, 10);
var_dump($content);
?>
string(0) ""
Некорректная обработка бинарных данных

Попытка вывести бинарные данные (например, изображение) как строку может привести к краху вывода или искажению.

<?php
$handle = fopen('image.jpg', 'rb');
$header = fread($handle, 100);
echo $header; // Может вывести "мусор"
?>
Изменения в новых версиях PHP

В PHP 8.0 и 8.1 значительных изменений в поведении функции fread не было. Однако, общий контекст типизации в PHP становится строже. Например, передача аргумента неверного типа теперь вызывает TypeError вместо предупреждения. В PHP 8.1.0 появилась возможность использовать читаемые ресурсы (stream resources) в качестве ключей в массивах, что косвенно может влиять на код, манипулирующий множеством потоков.

Важно отметить, что в PHP 8 улучшена обработка ошибок ввода-вывода, что делает работу с файловой системой более предсказуемой.

Расширенные примеры применения
Чтение и обработка бинарного файла (например, заголовка BMP)
Пример php
<?php
$fp = fopen('image.bmp', 'rb');
if ($fp) {
    // Чтение заголовка файла BMP (14 байт)
    $fileHeader = fread($fp, 14);
    // Проверка сигнатуры 'BM'
    if (substr($fileHeader, 0, 2) === 'BM') {
        echo 'Это файл BMP.\n';
        // Чтение размера файла из заголовка (байты 2-6)
        $fileSize = unpack('V', substr($fileHeader, 2, 4))[1];
        echo 'Размер файла: ' . $fileSize . ' байт\n';
    }
    fclose($fp);
}
?>
Это файл BMP.
Размер файла: 1275624 байт
Создание простого потокового загрузчика файлов с ограничением скорости
Пример php
<?php
function readFileChunked($filePath, $chunkSize = 8192, $delay = 100000) {
    $handle = fopen($filePath, 'rb');
    if ($handle) {
        while (!feof($handle)) {
            echo fread($handle, $chunkSize);
            flush();
            usleep($delay); // Искусственная задержка для ограничения скорости
        }
        fclose($handle);
        return true;
    }
    return false;
}
// readFileChunked('large_video.mp4', 65536, 50000);
?>
Использование с stream_set_read_buffer для управления буферизацией
Пример php
<?php
$fp = fopen('http://example.com/large', 'r');
if ($fp) {
    // Отключаем буферизацию чтения
    stream_set_read_buffer($fp, 0);
    $data = fread($fp, 1024); // Будет читать непосредственно из сетевого потока
    // ...
    fclose($fp);
}
?>
Чтение из процесса, запущенного через popen()
Пример php
<?php
$handle = popen('ls -la /tmp', 'r');
if ($handle) {
    echo '<pre>';
    while (!feof($handle)) {
        $output = fread($handle, 4096);
        echo htmlspecialchars($output);
    }
    echo '</pre>';
    pclose($handle);
}
?>
total 24
drwxrwxrwt  8 root root 4096 Dec  1 10:00 .
drwxr-xr-x 20 root root 4096 Nov 15 08:30 ..
...
Безопасное чтение файла с проверкой реального размера
Пример php
<?php
$filename = 'user_data.json';
$handle = @fopen($filename, 'rb');
if ($handle === false) {
    die('Не удалось открыть файл');
}
// Получаем размер безопасно
$fileSize = @filesize($filename);
if ($fileSize === false || $fileSize > 10 * 1024 * 1024) {
    die('Файл слишком большой или недоступен');
}
// Читаем с контролем размера
$content = $fileSize > 0 ? fread($handle, $fileSize) : '';
fclose($handle);
$data = json_decode($content, true);
?>

PHP fread function comments

En
Fread Binary-safe file read