当前位置:首页 > PHP教程 > php文件操作 > 列表

PHP判断文件是否存在再读取怎么写

发布:smiling 来源: PHP粉丝网  添加日期:2026-09-12 11:23:12 浏览: 评论:0 

最稳妥做法是先用is_file()判断文件存在且为普通文件,再用file_get_contents()读取并严格检查返回值是否为false;避免直接使用file_exists()(因对目录也返回true)和单独使用is_readable()(不保证文件存在),同时须处理竞态条件与大文件内存限制。

用 file_exists() 判断再读取最稳妥

直接用 file_get_contents() 读取不存在的文件会触发警告(Warning: file_get_contents(...): Failed to open stream),影响错误处理和日志清晰度。先判断再读取是标准做法,file_exists() 是专为这个场景设计的函数,它只检查路径是否存在且可访问,不关心内容或权限细节。

注意:file_exists() 对目录也返回 true,如果明确要读取文件,需额外排除目录:

用 is_file() 替代 file_exists() 更精准(推荐)

或组合使用:file_exists($path) && !is_dir($path)

避免用 is_readable() 单独判断——它不保证文件存在,只测权限,且在某些 NFS 或 SELinux 环境下可能误判

file_get_contents() 失败时不要忽略返回值

file_get_contents() 在失败时返回 false,不是空字符串。如果只做 if ($content) 判断,当文件内容恰好是 "0" 或空字符串时会被误判为失败。

正确写法必须严格比较返回值类型:

  1. $content = file_get_contents($path); 
  2. if ($content === false) { 
  3.     // 处理读取失败:文件不存在、无权限、磁盘满等 
  4.     error_log("Failed to read $path"); 
  5.     return null; 
  6. // 此时 $content 是 string 类型,可安全使用 

永远用 === false,不用 == false 或 !$content

即使已用 is_file() 判断过,仍建议对 file_get_contents() 做失败处理——因为判断和读取之间存在竞态窗口(文件可能被其他进程删除)

大文件别用 file_get_contents(),改用 fopen() 流式读取

如果文件可能超过几 MB,file_get_contents() 会一次性把全部内容载入内存,容易触发 memory_limit 错误,尤其在共享主机或低配环境中。

替代方案是手动打开流并分块读取:

  1. $handle = fopen($path'rb'); 
  2. if ($handle === false) { 
  3.     return null; // 文件不可读或不存在 
  4. $content = ''
  5. while (!feof($handle)) { 
  6.     $chunk = fread($handle, 8192); // 每次读 8KB 
  7.     if ($chunk === false) break
  8.     $content .= $chunk
  9. fclose($handle); 

用 'rb' 模式确保二进制安全,避免 Windows 下换行符干扰

fread() 返回 false 表示读取错误(如磁盘 I/O 故障),需检查

如果只需处理某一行或特定位置,更推荐 file()(按行读成数组)或 stream_get_line()

相对路径容易出错,优先用绝对路径

PHP 的当前工作目录(getcwd())不等于脚本所在目录(__DIR__),用相对路径如 "./data/config.json" 时,一旦在 CLI 下被其他目录调用,或通过 include 引入,就可能找不到文件。

安全做法是基于 __DIR__ 或 dirname(__FILE__) 构造绝对路径:

  1. $path = __DIR__ . '/data/config.json'
  2. if (is_file($path)) { 
  3.     $content = file_get_contents($path); 

避免拼接时漏掉 /:用 __DIR__ . '/file.txt',不要写 __DIR__ . 'file.txt'

Windows 下反斜杠不影响 is_file() 和 file_get_contents(),但统一用正斜杠更兼容

如果路径来自用户输入,必须用 realpath() 规范化并校验是否仍在预期根目录内,防止路径遍历攻击

实际项目里最容易被忽略的是竞态条件和内存限制——判断存在后立刻读取,中间仍可能失败;小文件图省事全读进内存,上线后某天突然 OOM。这两个点没处理好,问题往往出现在流量高峰或大文件导入场景。

Tags: PHP判断文件是否存在

分享到:

相关文章