本文目录导读:

是的,PHP支持流式输出,可以通过多种方式实现,以下是主要的实现方法:
基础流式输出
// 关闭输出缓冲
ob_end_flush();
// 设置响应头
header('Content-Type: text/plain; charset=utf-8');
header('X-Accel-Buffering: no'); // 禁用Nginx缓冲
// 流式输出
for ($i = 0; $i < 10; $i++) {
echo "Chunk $i\n";
flush();
sleep(1);
}
使用 Symfony Response 流式输出
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
// 创建流式响应
$response = new StreamedResponse(function() {
for ($i = 0; $i < 10; $i++) {
echo "Data chunk $i\n";
flush();
usleep(500000); // 0.5秒
}
});
$response->headers->set('Content-Type', 'text/plain');
$response->send();
使用 Laravel 流式响应
// Laravel 中的流式响应
Route::get('/stream', function () {
return response()->stream(function () {
for ($i = 0; $i < 10; $i++) {
echo "Chunk $i\n";
ob_flush();
flush();
sleep(1);
}
}, 200, [
'Content-Type' => 'text/plain',
'X-Accel-Buffering' => 'no'
]);
});
Server-Sent Events (SSE) 流式输出
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
while (true) {
$data = json_encode(['time' => date('H:i:s')]);
echo "data: $data\n\n";
ob_flush();
flush();
if (connection_aborted()) break;
sleep(1);
}
大文件流式下载
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="large_file.txt"');
$file = fopen('/path/to/large/file', 'rb');
while (!feof($file)) {
echo fread($file, 8192); // 每次读取8KB
ob_flush();
flush();
}
fclose($file);
重要注意事项
禁用输出缓冲
// 多个缓冲层都需要处理
@ini_set('output_buffering', 'off');
@ini_set('zlib.output_compression', false);
while (ob_get_level() > 0) {
ob_end_clean();
}
Nginx 配置
# 禁用缓冲 proxy_buffering off; fastcgi_buffering off;
Apache 配置
# 禁用缓冲 SetEnv no-gzip 1
检查连接状态
// 定期检查客户端是否断开连接
while (true) {
echo "data\n";
flush();
if (connection_aborted()) {
break;
}
usleep(100000);
}
实际应用场景
- 实时日志查看:实时输出系统日志
- 大数据导出:流式导出CSV/JSON数据
- 实时推送:SSE实现实时通知
- 视频流:分段传输视频内容
- AI对话:流式返回AI生成的内容
性能优化建议
// 1. 设置适当的缓冲区大小
$bufferSize = 4096; // 4KB
// 2. 使用输出控制
function streamOutput($callback, $bufferSize = 8192) {
@ini_set('output_buffering', 'off');
@ini_set('zlib.output_compression', false);
ob_implicit_flush(true);
while (ob_get_level() > 0) {
ob_end_flush();
}
$callback($bufferSize);
}
PHP通过底层函数和框架支持提供了完整的流式输出能力,适合各种实时数据传输场景。