fflush()
Функция fflush() в PHP принудительно записывает данные из буфера файлового указателя в поток. Синтаксис, параметры и примеры.
Введение в функцию PHP fflush()
Функция fflush() в PHP принудительно записывает данные, находящиеся в буфере записи файлового указателя, в базовый поток немедленно, вместо того чтобы ждать заполнения буфера или закрытия потока.
Когда вы вызываете fwrite(), PHP не обязательно сразу записывает байты на диск. Для повышения производительности данные собираются в буфере в памяти и записываются большими блоками. Обычно это именно то, что нужно — но иногда данные должны быть записаны прямо сейчас: для отслеживаемого лог-файла, долго работающего воркера, который читает другой процесс, или скрипта, который может быть прерван до завершения. fflush() — это функция, которая говорит: «не жди, запиши то, что есть».
На этой странице рассматриваются синтаксис, параметры, возвращаемое значение и несколько выполняемых примеров, а также распространённые ошибки — включая ключевое различие между fflush() и синхронизацией записи на уровне ОС.
Синтаксис
Синтаксис функции fflush() выглядит следующим образом:
Синтаксис PHP функции fflush()
bool fflush ( resource $stream )stream: файловый указатель для сброса буфера
Параметры
Функция fflush() принимает один обязательный параметр:
$stream: Файловый указатель для сброса буфера. Это должен быть допустимый ресурс потока, открытый для записи — как правило, возвращённый функциейfopen(). Потоки, открытые только для чтения (режим'r'), не имеют буфера для сброса.
Возвращаемое значение
fflush() возвращает true при успехе или false при неудаче. Функция завершается ошибкой, если ресурс не является допустимым открытым потоком или базовая операция записи не может быть выполнена; при этом может быть выдано предупреждение. Поскольку сбои редки, но возможны (полный диск, разрыв соединения), проверяйте возвращаемое значение, когда потеря данных недопустима:
<?php
if (fflush($stream) === false) {
// The buffered data could not be written — handle it (log, retry, abort).
}Примеры
Пример 1: Сброс буфера файлового указателя
Открыть файл, записать данные, затем сбросить буфер, чтобы байты попали в поток до продолжения выполнения скрипта:
Сброс буфера файлового указателя в PHP
<?php
$fileHandle = fopen('example.txt', 'w');
fwrite($fileHandle, 'Hello, World!');
if (fflush($fileHandle)) {
echo "Buffer flushed to the stream.\n";
}
fclose($fileHandle);Вывод:
Buffer flushed to the stream.Пример 2: Непрерывно сбрасываемый лог
Воркер, который дописывает записи в лог-файл и сбрасывает буфер после каждой записи, чтобы другой процесс мог выполнять tail -f по этому файлу и видеть строки в реальном времени, а не порциями:
Логирование в реальном времени с помощью fflush()
<?php
$log = fopen('worker.log', 'a');
foreach (['started', 'processing', 'done'] as $event) {
fwrite($log, date('c') . " {$event}\n");
fflush($log); // each line is visible immediately, not only at fclose()
}
fclose($log);Без вызова fflush() три строки обычно появлялись бы только при заполнении буфера или при вызове fclose() в конце.
fflush() и fclose()
Вам не нужно вызывать fflush() непосредственно перед fclose() — fclose() автоматически сбрасывает все оставшиеся буферизованные данные перед закрытием ресурса. Используйте fflush() только тогда, когда данные нужно записать пока файл ещё открыт.
fflush() не гарантирует запись данных на диск
Это наиболее распространённое заблуждение. fflush() передаёт буфер PHP операционной системе, но ОС ведёт собственный кэш записи. После fflush() байты могут по-прежнему находиться в кэше ОС, а не на физическом диске. Если машина потеряет питание сразу после этого, данные могут быть потеряны.
Чтобы принудить ОС зафиксировать данные на надёжном носителе, воспользуйтесь fsync() (PHP 8.1+):
<?php
$file = fopen('important.txt', 'w');
fwrite($file, 'critical data');
fflush($file); // PHP buffer -> OS
fsync($file); // OS cache -> physical disk (PHP 8.1+)
fclose($file);Управление самим буфером
Если вы хотите изменить объём буферизации PHP перед автоматической записью — вместо принудительного сброса по требованию — используйте set_file_buffer(). Установка размера буфера в 0 полностью отключает буферизацию, поэтому каждый fwrite() записывается без явного вызова fflush().
Замечание о буферизации вывода
Не путайте fflush() с функциями буферизации вывода PHP, такими как ob_flush() и flush(). fflush() работает с ресурсом файла/потока (файлы, сокеты, каналы). ob_flush() сбрасывает внутренний буфер вывода PHP (тело страницы) в сторону веб-сервера или клиента. Это несвязанные механизмы, которые случайно разделяют слово «flush».
Заключение
Функция fflush() — полезная функция PHP, которая гарантирует немедленную запись буферизованных данных в файловый поток. Она незаменима для приложений, требующих хранения данных в реальном времени, таких как системы логирования или скрипты обработки данных.
Используя примеры из этой статьи, вы должны теперь уметь применять функцию fflush() в своём PHP-коде без труда. Если у вас есть вопросы об использовании функции fflush() в PHP, не стесняйтесь обращаться к нам. Мы будем рады помочь.