file_put_contents写入失败应先检查返回值是否为false,再调用error_get_last()获取具体错误;常见原因包括SELinux拦截、父目录不存在或不可写、磁盘满、挂载只读及大文件内存溢出。

file_get_contents 读取失败时先查什么
直接返回 false 不代表文件不存在,更可能是权限或路径问题。PHP 进程(比如 www-data 或 apache 用户)必须对文件有读权限,且所有父目录都得有执行(x)权限才能进入——这点常被忽略。
- 用
is_readable('/path/to/file.txt')检查可读性,比单纯file_exists()更准确 - 路径别用相对路径(如
./config.json),优先用__DIR__ . '/config.json'避免上下文路径漂移 - 如果文件在 Web 根目录外(比如
/var/data/),确认 SELinux 或 AppArmor 没拦截访问(CentOS 7 上尤其常见)
fopen + fwrite 必须配 fclose 吗
必须。不关句柄不只是内存泄漏,还会在 Linux 下快速耗尽文件描述符(Too many open files 错误),尤其在循环或高并发场景下。
-
fopen()成功后,fclose()是硬性收尾动作,不能依赖脚本结束自动释放 - 写入中途出错(比如磁盘满),也要在
catch或finally块里fclose($handle) - 用
file_put_contents()可省略手动关闭,但它内部仍调用fopen/fwrite/fclose,只是封装了
追加日志为什么用 a 模式而不是 w
w 模式每次打开都会清空文件内容,而日志需要保留历史记录。a 模式把文件指针强制移到末尾,写入即追加,天然适合日志场景。
-
fopen('log.txt', 'a')和file_put_contents('log.txt', $msg, FILE_APPEND)效果等价 - 但
a模式本身不加锁,多个请求同时写可能乱序;生产环境务必配合flock($fp, LOCK_EX)或FILE_APPEND | LOCK_EX - 注意:
a+允许读写,但读操作仍从开头开始,写永远在末尾——除非你主动fseek(),一般日志不需要
大文件写入时 file_put_contents 会爆内存吗
会。它把整个字符串一次性加载进内存再写入磁盘,若内容超百 MB,极易触发 Allowed memory size exhausted。
立即学习“PHP免费学习笔记(深入)”;
- 处理大文件(如导出 CSV、备份 SQL)请改用
fopen('file', 'w') → fwrite() 分块 → fclose() - 每写 8192 字节(一个典型 buffer 大小)就
flush()一次,避免内核缓冲区堆积 - 生成器(
yield)配合fwrite是更优雅的流式写法,但 PHP 7.4 不支持yield from,需手动迭代
file_put_contents 加了 LOCK_EX,却忘了目标目录本身不可写,结果锁住了也写不进去。



















