Время чтения: 1 мин.
Неблокирующий вывод в PHP позволяет отправлять данные клиенту без ожидания завершения выполнения всего скрипта. Это особенно полезно для длительных операций, когда вы хотите начать отправку данных как можно раньше.
Основные методы неблокирующего вывода
- Функция
ob_implicit_flush()
с буферизацией
ob_implicit_flush(true);
ob_start();
// Отключаем сжатие (если используется)
if (function_exists('apache_setenv')) {
apache_setenv('no-gzip', '1');
}
// Отправляем данные по частям
for ($i = 0; $i < 10; $i++) {
echo "Часть данных $i<br>";
ob_flush();
flush();
sleep(1);
}
- Отключение буферизации
// Отключаем буферизацию на всех уровнях
@ini_set('output_buffering', 'Off');
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);
for ($i = 0; $i < 10; $i++) {
echo "Данные $i<br>";
flush();
sleep(1);
}
- Использование HTTP-заголовков для потоковой передачи
header('Content-Type: text/plain');
header('Cache-Control: no-cache');
for ($i = 0; $i < 10; $i++) {
echo "Блок данных $i\n";
flush();
sleep(1);
}
Особенности и рекомендации
- Проблемы с веб-серверами:
- Nginx может буферизировать вывод
- Apache может использовать mod_gzip
- Решение: отключать сжатие и буферизацию
- Для длительных операций:
set_time_limit(0); // Отключаем ограничение времени выполнения
ignore_user_abort(true); // Продолжать выполнение, даже если клиент отключился
- SSE (Server-Sent Events) — более современный подход:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
while (true) {
echo "data: " . json_encode(['time' => date('H:i:s')]) . "\n\n";
flush();
sleep(1);
}
- WebSockets — для двусторонней коммуникации (но это уже другой протокол, не HTTP).
Неблокирующий вывод особенно полезен для:
- Прогресс-баров длительных операций
- Потоковой передачи данных
- Реалтайм-уведомлений
- Долгих API-запросов с промежуточными результатами
Добавить комментарий