file_get_contents()适用于中小文件(≤10mb)且需简洁、自动编码处理的场景;大文件或逐行处理时应选fopen()+fgets();file()适合按行索引,readfile()用于直接输出。

PHP 读取文件内容最常用、最安全的方式是 file_get_contents(),它适合中小文件(通常 ≤ 10MB);大文件或需逐行处理时,应改用 fopen() + fgets() 或 file()(注意内存占用)。
什么时候该用 file_get_contents()
这是绝大多数场景的首选:代码简洁、自动处理编码(默认 UTF-8)、返回字符串便于后续处理(如 json_decode()、simplexml_load_string())。
常见错误现象:file_get_contents(): Failed to open stream: No such file or directory —— 多因路径错误或权限不足。
- 确保路径存在且 PHP 进程有读取权限(Linux 下注意
open_basedir限制) - 相对路径以当前执行脚本(
__FILE__)为基准,不是 webroot;建议用__DIR__ . '/data/config.json' - 如需处理 HTTP URL,确认
allow_url_fopen = On(但生产环境慎用,推荐cURL) - 超大文件会直接加载进内存,触发
memory_limit错误,此时必须换流式读取
fopen() + fgets() 逐行读大文件
当文件超过几 MB、或需边读边处理(如日志分析、CSV 导入),避免内存爆炸,必须用流式读取。
立即学习“PHP免费学习笔记(深入)”;
Android文件存取与数据库编程知识,文件操作主要是读文件、写文件、读取静态文件等,同时还介绍了创建添加文件内容并保存,打开文件并显示内容;数据库编程方面主要介绍了SQLite数据库的使用、包括创建、删除、打开数据库、非查询SQL操作指令、查询SQL指令-游标Cursors等知识。
典型错误:忘记 fclose() 导致文件句柄泄漏,或用 feof() 判断不当造成死循环。
- 始终检查
fopen()返回值是否为false,否则后续操作会报 Warning - 用
while (($line = fgets($fp)) !== false)而非while (!feof($fp))—— 后者在最后一行无换行符时会多读一次空行 -
fgets()默认最多读 1024 字节,长行会被截断;可传入长度参数,如fgets($fp, 8192) - 记得
fclose($fp),尤其在循环中打开多个文件时
file() 和 readfile() 的适用边界
file() 把文件按行拆成数组(含换行符),适合需按行索引处理的场景(如配置项查找);readfile() 直接输出到 stdout,常用于下载或图片直出,不经过 PHP 变量。
容易踩的坑:file() 会把整个文件载入内存并分割,比 file_get_contents() 更耗内存;readfile() 前若已输出内容(如空格、BOM),会导致 headers already sent 错误。
-
file()的第二参数可传FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES清理数组元素 -
readfile()返回实际字节数,可用于校验传输完整性,但不适用于需要修改内容的场景 - 用
readfile()输出二进制文件(如 PDF、ZIP)前,务必设置正确 header,如Content-Type: application/pdf和Content-Disposition
真正难的不是选哪个函数,而是判断文件大小、IO 模式和后续处理逻辑之间的匹配关系——比如读一个 50MB 的 JSONL(每行一个 JSON 对象)文件,file_get_contents() 会直接 OOM,而 file() 会更糟;这时候只能老老实实用 fopen() 流式解析。路径、权限、编码、内存,四个变量一动,方案就得重选。









