PHP处理JSON Lines文件怎么读写
发布:smiling 来源: PHP粉丝网 添加日期:2026-10-13 10:51:45 浏览: 评论:0
JSON Lines文件不能用json_decode(file_get_contents($file)),因为其每行是独立JSON值而非单个JSON对象,整文件解析会语法错误;须逐行读取并解码。
JSON Lines文件读取时为什么不能用 json_decode(file_get_contents($file))
因为 JSON Lines(.jsonl)不是单个 JSON 对象,而是每行一个独立的 JSON 值(对象、数组、字符串等),整文件直接 json_decode() 会失败,报错类似 JSON_ERROR_SYNTAX 或只解析第一行就终止。
正确做法是逐行读取 + 逐行解码:
用 file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) 一次性读入所有非空行(适合小到中等文件)
或用 fopen() + fgets() 流式读取(推荐,内存友好,适合大文件)
对每一行调用 json_decode($line, true);注意检查返回值是否为 null,并用 json_last_error() 判断是否解析失败
示例片段:
- if ($fp = fopen('data.jsonl', 'r')) {
- while (($line = fgets($fp)) !== false) {
- $line = trim($line);
- if ($line === '') continue;
- $data = json_decode($line, true);
- if ($data === null && json_last_error() !== JSON_ERROR_NONE) {
- error_log("JSON parse error on line: " . $line);
- continue;
- }
- // 处理 $data...
- }
- fclose($fp);
- }
写入 JSON Lines 文件时 json_encode() 的关键参数
每行必须是严格合法的 JSON 文本,且行尾不能有多余空格或换行符。常见错误是忘记 PHP_EOL 或误加逗号、括号。
每次写入前确保数据可被 json_encode() 序列化(无资源、无循环引用)
推荐加上 JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES 避免中文转义、URL 中斜杠被转义
必须手动追加 PHP_EOL(Windows 下是 "\r\n",但用 PHP_EOL 更安全)
不要用 file_put_contents($file, $json . PHP_EOL, FILE_APPEND) 循环写——频繁磁盘 I/O 慢;改用 fopen(..., 'a') + fwrite()
示例:
- $fp = fopen('output.jsonl', 'a');
- foreach ($rows as $row) {
- $json = json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
- if ($json === false) {
- error_log("JSON encode failed: " . json_last_error_msg());
- continue;
- }
- fwrite($fp, $json . PHP_EOL);
- }
- fclose($fp);
遇到中文乱码或特殊字符解析失败怎么办
JSON Lines 规范要求 UTF-8 编码,但 PHP 默认不校验输入编码。如果文件含 BOM 或混入 GBK 字节,json_decode() 会静默失败(返回 null)。
排查和修复步骤:
用 mb_detect_encoding($line, ['UTF-8', 'GBK'], true) 检查单行编码;若非 UTF-8,先 mb_convert_encoding($line, 'UTF-8', 'GBK')
用 hexdump -C file.jsonl | head 查看前几字节,确认无 EF BB BF(UTF-8 BOM);如有,需 ltrim($line, "\xEF\xBB\xBF")
json_last_error_msg() 返回 "Malformed UTF-8 characters" 就基本锁定编码问题
大文件处理时性能瓶颈在哪、怎么绕过
真正卡住的往往不是 JSON 解析本身,而是 I/O 和内存:一次 file() 读几百 MB 文件会爆内存;反复 fgets() 在机械硬盘上慢;json_decode() 对超长嵌套结构(如深度 > 512)也会变慢。
实用优化点:
用 stream_set_read_buffer($fp, 0) 关闭读缓冲(某些场景反而更快)
避免在循环里做日志输出或数据库插入;攒批处理(例如每 100 行 commit 一次)
对已知结构的数据,考虑用 json_decode($line, false, 512, JSON_BIGINT_AS_STRING) 控制深度和大整数处理
极端情况(GB 级)可结合 pcntl_fork() 分块读取,但要注意进程间文件指针不共享,得按字节偏移切分
最常被忽略的是:没关掉 Xdebug。开发环境开着 Xdebug 解析 10 万行 JSONL,速度可能差 5–10 倍。
Tags: JSON文件怎么读写 PHP文件怎么读写
- 上一篇:PHP处理文件读写怎么避免权限报错
- 下一篇:最后一页
推荐文章
热门文章
最新评论文章
- 写给考虑创业的年轻程序员(10)
- PHP新手上路(一)(7)
- 惹恼程序员的十件事(5)
- PHP邮件发送例子,已测试成功(5)
- 致初学者:PHP比ASP优秀的七个理由(4)
- PHP会被淘汰吗?(4)
- PHP新手上路(四)(4)
- 如何去学习PHP?(2)
- 简单入门级php分页代码(2)
- php中邮箱email 电话等格式的验证(2)
