php文件操作函数不抛异常,须手动检查返回值:file_get_contents失败返回false,preg_replace错误返回null,file_put_contents写入不完整或清空原文件,均需显式判断并处理。

PHP替换文件内容时,file_get_contents和file_put_contents本身不抛出异常,错误全靠返回值和系统级错误报告机制兜底;不主动检查失败状态,脚本会静默损坏文件或写空。
file_get_contents失败时不报错,只返回false
常见现象:file_get_contents读取权限不足、路径不存在、磁盘满时,直接返回false,而非抛出Exception。若后续直接传给preg_replace,会导致“Warning: preg_replace(): Parameter mismatch”,甚至把false当字符串处理,写回空内容。
- 务必在调用后立即判断:
if ($content === false) { throw new RuntimeException('Failed to read ' . $path); } - 不要依赖
@file_get_contents压制警告——它同时屏蔽了真实错误线索 -
error_get_last()可补查最后一次底层错误,但仅限当前请求周期内最近一次
file_put_contents写入失败可能丢数据
典型问题:目标目录不可写、磁盘空间不足、NFS挂载中断时,file_put_contents返回false,但原文件已被清空(因默认截断模式)。若没检查返回值,就等于“成功替换了空文件”。
- 写入前加
is_writable(dirname($path))预检目录权限 - 写入后必须验证返回字节数:
$written = file_put_contents($path, $content, LOCK_EX | FILE_BINARY); if ($written !== strlen($content)) { /* 写入不完整 */ } - 关键文件务必先
copy($path, $path . '.bak'),失败时可回滚
正则替换失败时preg_replace返回null而非原串
当preg_replace的模式语法错误(如括号不匹配)、PCRE栈溢出、或超时(pcre.backtrack_limit触发),函数直接返回null。若代码假设它“总会返回字符串”,就会把null写进文件,导致内容被破坏。
- 永远用
=== null显式判断:if ($new_content === null) { throw new RuntimeException('preg_replace failed: ' . preg_last_error_message()); } -
preg_last_error()返回整型错误码,需配合preg_last_error_message()(PHP 7.2+)获取可读提示 - 避免在循环中反复调用
preg_replace——编译开销大,且错误累积难定位
流式处理时fopen/fgets的错误被忽略
大文件用fopen逐行处理时,fopen失败返回false,fgets读到末尾返回false,两者语义完全不同。混为一谈会导致提前退出或死循环。
-
fopen后立刻检查:$fp = fopen($path, 'r'); if (!$fp) { throw new RuntimeException("Cannot open $path"); } -
fgets返回false只表示EOF或读取失败,需用feof($fp)区分;读取中出错应调用fclose($fp)并清理临时文件 - 写入新文件时,
fwrite返回false或字节数小于预期,必须中断并删除未完成的.new文件
最易被忽略的是:所有这些函数的错误信号都依赖手动检查返回值,PHP不会自动中断执行或抛异常——哪怕你启用了error_reporting(E_ALL),也捕获不到file_get_contents返回false这种“业务失败”。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











