直接用file_get_contents+file_put_contents读写备忘录需加权限校验、临时文件原子写入、换行符统一处理三步,否则线上易丢数据;fopen('w')覆盖写在并发或中断时风险最高,会导致文件截断、内容覆盖及换行符混乱。

直接用 file_get_contents + file_put_contents 就能完成绝大多数文本备忘录的读写与修改,但必须加权限校验、临时文件原子写入、换行符统一处理这三步,否则线上一改就丢数据。
为什么不能直接 fopen/fwrite 覆盖写入备忘录文件
看似最“原始”的方式,实际在并发或异常中断时风险最高:写到一半进程崩溃,原文件内容被截断;多个请求同时写同一个文件,内容相互覆盖;Windows 和 Linux 换行符混用导致前端渲染错乱。
-
fopen($file, 'w')会清空原文件再写,没写完就崩 = 永久丢失 - 没检查
is_writable($file),失败时file_put_contents返回false但不报错,前端以为成功 - 没用
PHP_EOL而是硬写"\n",Linux 写的文件在 Windows 编辑器里变成一行
file_get_contents + str_replace 修改配置类文本的实操要点
这是修改 .ini、.env、.txt 等纯文本配置最常用组合,但要注意替换逻辑是否精确。
- 用
preg_replace替代str_replace更安全,比如匹配^debug\s*=\s*off$防止误改注释行或子字符串 - 修改前先
copy($file, $file . '.bak')备份,尤其对/etc/或/var/www下的关键文件 - 写入后调用
chmod($file, 0644)确保权限没被意外重置(某些 FTP 工具或部署脚本会改掉) - 别省略返回值判断:
if (file_put_contents($file, $content) === false) { die('写入失败:' . error_get_last()['message']); }
大文件(>50MB)备忘录内容替换必须用流式处理
用 file_get_contents 读取 100MB 日志文件,PHP 进程内存直接飙到 200MB+,超限被系统 kill 是常事。此时必须放弃“全量加载”思路。
立即学习“PHP免费学习笔记(深入)”;
- 用
fopen($file, 'c')打开(c模式不截断,可读可写,指针在开头) - 逐行
fgets()+fseek()定位 +fwrite()原地覆盖,适合固定长度字段替换 - 更稳妥的做法:打开原文件读,同时打开临时文件写,最后
rename($temp_file, $original_file)——rename在同一文件系统下是原子操作,不会出现中间态 - 记得
fflush($fp)和fclose($fp),否则缓冲区内容可能滞留不落盘
真正容易被忽略的不是语法,而是文件系统行为:PHP 的文件函数不保证跨平台原子性,file_put_contents 的 FILE_APPEND 标志在 NFS 共享目录上可能失效,rename 替换在不同磁盘分区会失败并报 EXDEV 错误——这些都得在 try/catch 里捕获并降级处理。



















