w模式每次打开文件都会清空全部内容并重置指针,即使已写入一次,第二次fopen("log.txt","w")仍会清空;a模式在末尾追加且不破坏原有数据,但需确保文件可写、有权限且未被独占打开。

为什么用 w 模式写两次,第一次的内容就没了?
因为 w 模式每次打开文件时都会清空全部内容,把指针重置到开头。哪怕文件刚被你写过一次,第二次 fopen("log.txt", "w") 就会把它变回空文件。
常见错误场景:循环里反复用 w 写日志、表单提交后多次调用写入函数、没关文件句柄就重开 —— 全部导致前序数据丢失。
- ✅ 正确做法:只在初始化或需覆盖时用
w,比如生成配置模板、重置缓存文件 - ❌ 错误习惯:把
w当成“安全写入”用,以为它会自动追加或合并 - ⚠️ 注意:即使
fclose()了,下次再fopen(..., "w")仍会清空 —— 模式行为与是否关闭无关
a 模式真能“不破坏原有数据”吗?
能,但有前提:文件必须可写,且 PHP 进程有权限在末尾追加。它不会清空、不会移动已有内容,只把新数据拼在最后。
典型适用场景:访问日志、操作审计、用户行为记录 —— 所有需要保留历史痕迹的写入。
立即学习“PHP免费学习笔记(深入)”;
- ✅ 推荐搭配
flock($fp, LOCK_EX),避免并发写入时出现内容错位(尤其多进程/高并发) - ❌ 不要指望
a能自动换行:fwrite($fp, "msg")后若没加\n,下一条会紧贴着写 - ⚠️ 注意:如果文件被其他程序以独占方式打开(如 Windows 下被记事本编辑中),
fopen(..., "a")可能失败并返回false
比 fopen+fwrite 更省心的写法
多数简单写入不需要手动管理句柄,file_put_contents() 是更安全的选择。
它默认行为是 w,但加 FILE_APPEND 标志就等效于 a 模式,还自带原子写入和可选加锁:
file_put_contents("log.txt", "user login\n", FILE_APPEND | LOCK_EX);
- ✅
LOCK_EX避免并发写乱序(比手写flock简洁) - ✅ 返回写入字节数,方便做基础校验(比如检查是否为 0)
- ⚠️ 注意:
file_put_contents()不支持部分写入或流式写入,大数据量或需分块处理时仍得用fopen
PHP 7.4 下写文件容易忽略的权限细节
不是所有服务器都默认给 Web 进程写权限。即使模式选对了,fopen 还是返回 false,大概率是权限问题。
关键点不在代码里,而在部署环境:
- ✅ 检查文件所在目录的属组是否包含 Web 用户(如
www-data或apache),权限建议设为755(目录) /644(文件) - ✅ 使用
is_writable()提前判断,别等fopen失败才报错 - ⚠️ 注意:
file_put_contents()创建新文件时,权限由umask控制,默认可能只有600,外部脚本或命令行无法读取 —— 显式传0644更可控
w 和 a 真正落地的关键。



















