You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP打开修改JSON文件时fopen的r+/w+/a+模式选择问题

关于PHP fopen模式适配JSON文件更新的解答

三个候选模式的排除与选择

你筛选的三个模式中,仅r+适配你的需求,另外两个模式的特性验证如下:

  • w+:截断操作发生在文件打开的瞬间,只要调用fopen时指定该模式,原有内容会被立即清空,你还没读取旧的JSON数据就会拿到空内容,直接排除。
  • a+:你的判断完全正确,该模式强制所有写入操作定位到文件末尾,即使手动移动指针到开头也不会生效,无法实现整个JSON文件的覆盖更新,直接排除。
  • r+:打开文件时指针定位在开头,写入操作是直接覆盖指针位置的原有内容,不存在自动插入逻辑。你需要注意的坑是:如果新JSON内容长度短于旧内容,覆盖后文件末尾会残留旧内容的多余字符,导致JSON解析失败,处理方法是写入新内容后手动截断文件多余部分。

基于r+的标准实现流程

完整的操作需要加独占锁避免并发写入异常,步骤如下:

  1. 用r+模式打开JSON文件,调用flock($fp, LOCK_EX)加独占锁
  2. 读取文件全量内容,解析为PHP数组
  3. 用array_unshift将新博文信息插入到数组开头
  4. 将新数组编码为JSON字符串
  5. 调用rewind($fp)将文件指针移回开头
  6. 写入新的JSON字符串
  7. 调用ftruncate($fp, ftell($fp))截断指针后残留的旧内容
  8. 解锁、关闭文件句柄

更适配小体量场景的简化实现

你当前的场景文件体积小、无高并发压力,完全可以用更简单的读写函数组合,避免fopen的模式坑:

// 定义JSON文件路径
$jsonPath = __DIR__ . '/posts.json';
// 读取原有内容,解析失败时默认用空数组
$postList = json_decode(file_get_contents($jsonPath), true) ?: [];
// 构造新博文数据
$newPost = [
    'title' => '新博文标题',
    'author' => '作者名',
    'date' => date('Y-m-d H:i:s'),
    'link' => '/新文章目录路径/'
];
// 插入到数组开头
array_unshift($postList, $newPost);
// 写回文件,保留格式、不转义中文
file_put_contents(
    $jsonPath,
    json_encode($postList, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);

该方案代码量少、可读性高,完全满足你练习文件操作和JSON处理的需求。

内容的提问来源于stack exchange,提问作者Anthony LoPrimo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:18:04