*{box-sizing: border-box; } body {margin: 0;}*{box-sizing:border-box;}body{margin-top:0px;margin-right:0px;margin-bottom:0px; margin-left:0px;}。
有两个原因使你可能想用PHP逐行读取文件。第一是你正在做的项目要求你逐行处理文件。第二是你正在读取一个非常大的文件,而唯一不超过内存限制的方法就是一行一行地读取。
使用file() 来读取文件
你可以使用PHP中的file() 函数将整个文件一次读入一个数组。数组元素是文件的各个行。所以你可以通过迭代数组来迭代文件中的每一行。该函数接受三个参数:
- 文件名:这是你想要读取的文件。你也可以提供一个URL作为文件名。
- 标志:这是一个可选的参数,可以设置为以下一个或多个常量值。
FILE_USE_INCLUDE_PATH,FILE_IGNORE_NEW_LINES和FILE_SKIP_EMPTY_LINES。 - 上下文:这也是一个可选的参数,用于修改流的行为。
我们将使用FILE_SKIP_EMPTY_LINES 标志来跳过一个文件中的所有空行。你可能还想使用FILE_IGNORE_NEW_LINES 来删除个别行的行尾。
这个函数成功时返回一个包含文件内容的数组,失败时返回false 。如果文件不存在,你还会得到一个E_WARNING 的错误。下面是一个使用这个函数的例子:
<?php
$lines = file('pride-and-prejudice.txt');
$count = 0;
foreach($lines as $line) {
$count += 1;
echo str_pad($count, 2, 0, STR_PAD_LEFT).". ".$line;
}
?>
上述代码的输出看起来像这样。
01. The Project Gutenberg eBook of Pride and Prejudice, by Jane Austen
02.
03. This eBook is for the use of anyone anywhere in the United States and
04. most other parts of the world at no cost and with almost no restrictions
05. whatsoever. You may copy it, give it away or re-use it under the terms
06. of the Project Gutenberg License included with this eBook or online at
07. www.gutenberg.org. If you are not located in the United States, you
08. will have to check the laws of the country where you are located before
09. using this eBook.
10.
11. Title: Pride and Prejudice
12.
13. Author: Jane Austen
14.
15. Release Date: June, 1998
16. [Most recently updated: August 23, 2021]
你可以看到,输出中有一些空行,我们可以通过使用FILE_SKIP_EMPTY_LINES 标志来消除它们。另外,可能不明显,但上面的行包括换行符。这就是为什么我们在回显这些行时不需要自己添加换行符。你可以通过使用FILE_IGNORE_NEW_LINES 标志来摆脱空行的影响:
<?php
$lines = file('pride-and-prejudice.txt', FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES);
$count = 0;
foreach($lines as $line) {
$count += 1;
echo str_pad($count, 2, 0, STR_PAD_LEFT).". ".$line;
}
?>
带有这些标志的输出将看起来像这样:
01. The Project Gutenberg eBook of Pride and Prejudice, by Jane Austen 02. This eBook is for the use of anyone anywhere in the United States and 03. most other parts of the world at no cost and with almost no restrictions 04. whatsoever. You may copy it, give it away or re-use it under the terms 05. of the Project Gutenberg License included with this eBook or online at 06. www.gutenberg.org. If you are not located in the United States, you 07. will have to check the laws of the country where you are located before 08. using this eBook. 09. Title: Pride and Prejudice 10. Author: Jane Austen 11. Release Date: June, 1998 [eBook #1342] 12. [Most recently updated: August 23, 2021]
如果你不担心内存的使用,使用file() 函数是在PHP中逐行读取文件的一个简单方法。然而,如果内存的使用是个问题的话,就必须要有更多的创意,因为file() ,一次就把整个文件读到一个数组中。
使用fgets() 来读取文件
另一种用PHP逐行读取文件的方法是使用fgets() 函数。它有一个必要的参数,就是一个有效的文件柄。我们将使用fopen() 函数来获取文件句柄。下面是我们将要运行的代码:
<?php
$file_handle = fopen('pride-and-prejudice.txt', 'r');
function get_all_lines($file_handle) {
while (!feof($file_handle)) {
yield fgets($file_handle);
}
}
$count = 0;
foreach (get_all_lines($file_handle) as $line) {
$count += 1;
echo $count.". ".$line;
}
fclose($file_handle);
?>
在第一行,我们以只读模式打开我们的文件。然后,我们定义一个函数,接受一个$file_handle 作为参数,并返回一个单行。请注意,我们使用的是yield 语句,我们的函数get_all_lines() 是一个生成器函数。如果你以前没有使用过生成器函数,你可能想阅读一下PHP中的生成器函数:
我们正在使用get_all_lines() 内的函数feof() ,以检查我们的文件指针是否已经到达文件末端。只要我们没有到达文件的末尾,我们就会产生。通过运行上面的代码,你应该得到以下输出:
1. The Project Gutenberg eBook of Pride and Prejudice, by Jane Austen
2.
3. This eBook is for the use of anyone anywhere in the United States and
4. most other parts of the world at no cost and with almost no restrictions
5. whatsoever. You may copy it, give it away or re-use it under the terms
6. of the Project Gutenberg License included with this eBook or online at
7. www.gutenberg.org. If you are not located in the United States, you
8. will have to check the laws of the country where you are located before
9. using this eBook.
10.
11. Title: Pride and Prejudice
12.
13. Author: Jane Austen
14.
15. Release Date: June, 1998
16. [Most recently updated: August 23, 2021]
输出结果看起来与我们上一节相同。这次唯一的区别是,你不再有内存耗尽的危险了。
我在前面提到,fgets() 将允许你一次读取文件的一行,它只需要一个参数,指向你要读取的文件的文件指针。在这种情况下,内存的消耗将取决于行的长度,而且你的内存有一点耗尽的可能性。
然而,假设你正在读取一个包含异常长行的文本文件。然后,你可以向fgets() 函数传递一个可选的第二个参数,指定你要读取的字符数。然后它将从文件中读取length - 1 字节,然后停止。如果遇到换行或文件结束,它将提前停止。这让你对你的代码的内存消耗有了更多的控制。
最后的思考
在本教程中,我已经讨论了用PHP逐行读取文件的两种方法。还有一些方法,但这两种方法几乎可以满足你所有的需要。当内存消耗不是问题时,请使用file() ,如果你想节省内存,请将fgets() 与生成器函数一起使用。