概述
在PHP开发中,读取文件是最基础也是最重要的操作之一。当处理大型文件时,逐行读取比一次性读取整个文件更加高效和安全。本文将详细讲解PHP中逐行读取文件的实现方法。
核心函数介绍
fopen() - 打开文件
$file = fopen("filename.txt", "r");
fopen() 函数用于打开文件或URL,返回一个文件指针(资源)。常用模式:
- r - 只读,指针在文件开头
- r+ - 读写,指针在文件开头
- w - 只写,清空文件内容(写模式)
- a - 追加写入,指针在文件末尾
fgets() - 逐行读取
echo fgets($file);
fgets() 函数从文件指针中读取一行内容,每次调用读取一行,到达文件末尾时返回 false。
feof() - 检测文件结束
while(!feof($file)) { ... }
feof() 函数检测是否已到达文件末尾(EOF),如果文件指针到达末尾或发生错误则返回 true。
fclose() - 关闭文件
fclose($file);
fclose() 函数关闭一个已打开的文件指针,释放资源,这是一个良好的编程习惯。
基础示例(完整代码)
以下是一个逐行读取文件的基础示例,来源于经典教程:
<?php
$file = fopen("Minot.txt", "r") or exit("Unable to open file!");
// Output a line of the file until the end is reached
// feof() check if file read end EOF
while(!feof($file))
{
// fgets() Read row by row
echo fgets($file). "<br>";
}
fclose($file);
?>
代码解析
- 打开文件:使用
fopen("Minot.txt", "r")以只读模式打开文件,若失败则退出 - 循环读取:使用
while(!feof($file))循环,直到文件末尾 - 逐行输出:
fgets($file)每次读取一行,加上<br>换行符 - 释放资源:使用
fclose($file)关闭文件
注意事项:
fgets() 会保留行末的换行符,使用时需要注意清理。如果需要不含换行符的内容,可以使用 trim(fgets($file))。
进阶用法 - 逐行读取并处理
在实际开发中,我们可能需要对每一行进行处理,例如过滤空行、统计行数等:
<?php
$file = fopen("data.txt", "r");
if (!$file) {
die("无法打开文件");
}
$lineNumber = 0;
while (($line = fgets($file)) !== false) {
$lineNumber++;
$line = trim($line);
if (empty($line)) {
continue;
}
echo "第 {$lineNumber} 行: " . htmlspecialchars($line) . "<br>";
}
fclose($file);
echo "<p>共读取 {$lineNumber} 行</p>";
?>
其他常用文件读取方法对比
方法一:file() 函数(读取整个文件到数组)
$lines = file("filename.txt");
foreach ($lines as $line_num => $line) {
echo "Line #{$line_num}: " . htmlspecialchars($line) . "<br>";
}
方法二:file_get_contents() + explode()
$content = file_get_contents("filename.txt");
$lines = explode("\n", $content);
foreach ($lines as $line) {
echo htmlspecialchars($line) . "<br>";
}
方法三:SplFileObject(面向对象方式)
$file = new SplFileObject("filename.txt");
while (!$file->eof()) {
echo $file->fgets() . "<br>";
}
$file = null;
性能对比
| 方法 | 内存占用 | 适用场景 | 推荐度 |
|---|---|---|---|
| fopen + fgets 逐行读取 | 低 | 大文件、逐行处理 | 强烈推荐 |
| file() 数组读取 | 高 | 小文件、需要数组处理 | 一般 |
| file_get_contents() | 很高 | 小文件、整体处理 | 一般 |
| SplFileObject | 低 | OOP场景、大文件 | 推荐 |
最佳实践
- 大文件务必使用 fopen + fgets 逐行读取,避免内存溢出
- 使用 or die/exit 处理文件打开失败的情况
- 读取完毕后一定要 fclose() 关闭文件
- 输出内容时使用 htmlspecialchars() 防止XSS攻击
- 使用 trim() 去除每行首尾的空白字符
实际应用案例
读取日志文件并筛选
<?php
$file = fopen("access.log", "r");
$errorCount = 0;
while (($line = fgets($file)) !== false) {
if (stripos($line, "error") !== false) {
$errorCount++;
echo htmlspecialchars($line) . "<br>";
}
}
fclose($file);
echo "共发现 {$errorCount} 条错误记录";
?>
CSV文件逐行解析
<?php
$file = fopen("data.csv", "r");
while (($data = fgetcsv($file)) !== false) {
echo "姓名: {$data[0]}, 年龄: {$data[1]}<br>";
}
fclose($file);
?>
总结
PHP提供了丰富的文件读取函数。对于逐行读取需求,推荐使用 fopen + fgets + feof + fclose 的组合,这是最经典也是最实用的方式,内存占用小,适合处理各种大小的文件。
本文参考自经典技术博客教程,整理优化分享。

发表评论 取消回复