Действие функции fflush()

284
18 мая 2022, 03:20

Не понимаю, какое действие выполняет функция php fflush(). В следующем примере у неё как будто нет никакого эффекта:

<?php
echo "<pre>";
$filename = '../app/files/bar.txt';
$file = fopen($filename, 'r+');
rewind($file);
echo PHP_EOL;
fwrite($file, 'Foo'); //Запись в файл происходит сразу же
readfile($filename);
echo PHP_EOL;
fflush($file); //То есть эта функция не даёт эффекта какой-то форсированной записи
readfile($filename);
echo PHP_EOL;
ftruncate($file, ftell($file));
readfile($filename);
echo PHP_EOL;
fwrite($file, 'Foo');
readfile($filename); //Все изменения в файлах видны сразу же
echo PHP_EOL;
fclose($file);
echo "</pre>";

Эксперименты типа

echo "Foo";
ob_flush();
fflush();

тоже не дают эффекта, то есть в файл не поступают данные системного буфера.

Расскажите, кто знает, чем эта функция вообще может быть полезна.

Answer 1

fflush вызывает метод соответствующего streams API php_stream_flush, который должен вести себя аналогично ANSI stdio функции, то есть, fflush стандартной библиотеки C:

These (should) behave in the same way as the ANSI stdio functions with similar names: fread, fwrite, fprintf, feof, fgetc, fgets, fclose, fflush, fseek, ftell, flock.

man 3 fflush по системной библиотеке, в свою очередь отвечает:

DESCRIPTION For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream's underlying write function.

NOTES Note that fflush() flushes only the user-space buffers provided by the C library. To ensure that the data is physically stored on disk the kernel buffers must be flushed too, for example, with sync(2) or fsync(2).

Этот вызов требует, чтобы были отправлены на запись все буферы в пользовательском пространстве (но могут оставаться буферизованными в пространстве ядра операционной системы, а потому fflush не гарантирует запись на физические накопители данных).

Тонкий момент именно в том, что системный fwrite может быть буферизован системной библиотекой (и отдельно - ядром системы). А может и нет (что, насколько помню, как раз справедливо для операций над файлами - не буферизуются системной библиотекой, только уже ядром). Или к моменту когда вы это проверяете уже запись из буфера была произведена. fflush даёт возможность явным образом гарантировать, что запись из локального буфера программы была выполнена.

Дальше надо уходить в тонкости стандартной библиотеки C и стандартов в частностях, не имеющих отношения к PHP. На ruSO наверняка есть более детальные ответы применительно именно к C, например этот. Да и, в сущности, в типичной модели использования PHP: получили http запрос, сгенерировали ответ и завершились - очень редко где fflush или fsync могут потребоваться. Каноничный пример использования fflush - это текстовый интерактивный интерфейс, когда вы выводите на консоль вопрос пользователю, а этот текст вместо консоли сначала попадает в буфер и потому не отображается.

READ ALSO
Отдать файл для скачивания пользователю

Отдать файл для скачивания пользователю

Отправляю POST с параметрами, получаю файл на скачиваниеПробую сделать подобное на php, но в консоле вижу только содержимое файлы, как отдать...

250
Redirect Laravel когда товар внизу списка

Redirect Laravel когда товар внизу списка

Всем приветДелаю тестовый инет магазин, когда кто то добавляет товар в корзину я поставил return redirect()->back();

161
Почему тег HTML не работает в php коде Laravel

Почему тег HTML не работает в php коде Laravel

Делаю flash уведомления, хочу чтобы название товара выделялось жирным, поэтому добавил тег , но он чего то не срабатываетВероятно банальная...

307
цикл с записью в массив

цикл с записью в массив

есть такой код, мне нужно выполнить этот код N количество раз, и записать в массив, то есть $arr = ['3%' => 'Выпало столько то раз'], что бы при каждой...

191