php不能用json_encode()一次性处理大结果集,因会耗尽内存导致崩溃;应逐行fetch、即时encode输出,配合flush控制流式json格式,并用生成器进一步降低内存占用。

PHP直接输出JSON流时为什么不能用json_encode()一次性处理?
因为大结果集会吃光内存,json_encode()必须把整个数组加载进内存才能序列化。10万行数据可能占用几百MB,PHP进程直接崩溃或超时。真实场景里,数据库查出几十万条记录再拼成大数组,是典型的内存陷阱。
正确做法是边查边输出,不缓存完整结果集,也不构造完整PHP数组。核心原则:查询用PDO::FETCH_ASSOC逐行获取,每行立刻json_encode()并echo,中间加逗号和换行控制格式。
- 必须关闭输出缓冲:
ob_end_flush()或ob_implicit_flush(true) - 每次
echo后调用flush()和ob_flush(),否则Web服务器(如Nginx)可能攒着不发 - 首行输出
[,末行输出],中间每行结尾加,——但最后一行不能有逗号,需用计数或标志位判断
如何安全生成合法的JSON流(含开头/结尾/逗号逻辑)?
手动拼接[、]和逗号看似简单,但容易出错:比如空结果集输出[],单行结果不能带尾逗号,网络中断时JSON不闭合。最稳的方式是用状态变量控制结构:
echo '[';
$first = true;
foreach ($stmt as $row) {
if (!$first) echo ',';
echo json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$first = false;
flush();
ob_flush();
}
echo ']';
注意:JSON_UNESCAPED_UNICODE避免中文变\uXXXX,JSON_UNESCAPED_SLASHES减少转义长度;flush()前确保output_buffering在php.ini中设为Off或0,否则ob_flush()无效。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
使用yield配合生成器能否进一步降低内存?
可以,而且更干净。把数据库遍历封装成生成器函数,天然实现“按需产出”,不保留历史行引用,GC能及时回收。但要注意PDO Statement本身不是可遍历的生成器,需显式yield:
function streamQuery(PDO $pdo, string $sql) {
$stmt = $pdo->prepare($sql);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
yield $row;
}
}
echo '[';
$iter = streamQuery($pdo, 'SELECT id,name FROM users');
$first = true;
foreach ($iter as $row) {
if (!$first) echo ',';
echo json_encode($row, JSON_UNESCAPED_UNICODE);
$first = false;
flush(); ob_flush();
}
echo ']';
生成器方式下,即使SQL返回百万行,PHP内存占用也稳定在几MB内。但别在生成器里做复杂计算或缓存,否则抵消优势。
响应头和客户端兼容性有哪些硬性要求?
只设Content-Type: application/json不够。流式JSON需要明确告知客户端“这是分块传输”,否则前端fetch().json()会等整个响应结束才解析,失去流式意义:
- 必须输出
Content-Type: application/json - 推荐加
X-Content-Type-Options: nosniff防MIME嗅探干扰 - 关键:设置
Transfer-Encoding: chunked(由flush()自动触发,无需手动写) - 避免设置
Content-Length,否则浏览器无法流式读取 - 前端用
response.body.getReader()配合TextDecoder逐段解析,而不是response.json()
真正难的不是PHP端输出,而是客户端能否持续接收并增量解析——很多前端框架默认不支持JSON流,得自己写解析器,遇到非法字符或断连就得容错重试。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










