PHP 8中输入和输出流的入门方法
在服务器端环境中处理文件是一项常见的任务,但它仍然很复杂。然而,大多数的PHP安装并没有提供足够的内存来处理大文件。
在本教程中,我们将学习如何使用流的概念在PHP中处理大文件。
先决条件
要继续学习本教程,你将需要以下条件。
- PHP的基本知识。
- PHP流的基本概念。
- 本地开发环境。
教学目的
本教程将教你如何使用流来处理PHP中的大文件。到最后,你会体会到流比传统文件系统的好处。
开始使用流
流是PHP中一个引人注目的概念。它允许你在没有内存问题的情况下处理大文件。
流简化了读和写文件的过程。它们的工作原理是提供一种以块为单位读写数据的方式。
这种按需读取数据的方式确保你不必将整个文件加载到内存中。
值得注意的是,PHP安装有一个内存限制。所以如果你试图加载一个太大的文件,你会得到一个错误。流有实现包装器,允许你处理特定的协议。
文件系统处理程序
为了理解文件系统处理程序,让我们在/tmp 目录中创建一个名为test.txt 的文件。
继续并在该文件中添加文本。在我们的例子中,test.txt 将包含以下文本。
hello world
接下来,打开streams.php 文件并添加以下代码。
<?php
$content = file_get_contents(__DIR__ . '/test.txt');
echo $content;
在上面的代码中,我们使用file_get_contents() 函数来读取文件的内容。
当我们运行上述代码时,我们得到以下结果。
hello world
你注意到,这段代码运行得很顺利。然而,在处理大文件时,情况并不总是如此,如下图所示。
<?php
$content = file_get_contents(__DIR__ . '/large-test-file.txt');
echo $content;
当运行上述代码时,你会得到以下错误。
# php fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 524288 bytes) in /tmp/streams.php on line 3
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1048576000 bytes)
上述错误是因为文件太大,无法加载到内存中。我们可能记得,PHP的内存限制设置为128M 。
现在我们了解了处理大文件的问题,让我们在下一节介绍流的概念。
使用流的工作
之前,我们已经看到了PHP的默认配置是如何限制我们在设定的内存限制内工作的。
在这一节中,让我们首先创建一个样本脚本,利用流的概念来解决我们上面的错误。
//open the stream.php file and add the following:
<?php
$large_file = fopen(__DIR__ . '/large-test-file.txt', 'r');
//the result is printed until the end of the file
while(! feof($large_file)) {
$endLine = fgets($large_file);
echo $endLine. "<br>";
}
fclose($large_file);
在上面的代码中,我们使用fopen() 函数来打开文件。fopen() 函数接收了2个参数。第一个是文件路径,第二个是模式。
接下来,我们使用fgets() 函数来读取文件的内容。最后,我们使用fclose() 函数来关闭文件。
当你执行上面的代码时,你注意到它没有给你一个错误,就像我们使用file_get_contents() 函数时那样。这就是流的力量。
有了流,我们可以读取任何大小的文件,而不会遇到内存管理问题,这可能会让开发人员感到沮丧。
检索文件内容
在上一节中,我们已经看到了如何在PHP中使用流的力量来处理大文件,在我们的例子中,使用fopen() 函数。
现在,让我们了解如何使用fgets() 函数来检索文件的内容。
...
while(! feof($large_file)) {
$endLine = fgets($large_file);
echo $endLine. "<br>";
}
...
在上面的代码中,我们有一个while 循环,将运行到文件的末尾。如果到达文件的末尾,feof() 函数将返回true 。
接下来,fgets() 函数将文件流作为第一个参数。然后我们使用echo 函数来打印文件的内容。
写入文件
现在我们已经了解了如何使用流的概念来读取文件内容,让我们在本节中学习如何向文件写入。
让我们在/tmp 目录中再创建一个名为test2.txt 的文件,以简化我们的流代码。
注意:我们已经在
/tmp目录下创建了一个叫test.txt的文件。如果它不在那里,你应该创建它。
在下面的脚本中,我们将读取文件test.txt 的内容并将其写入文件test2.txt ,如下所述。
<?php
//open the stream.php file and add the following:
// the source file
$file_stream_source = fopen(__DIR__ . '/test.txt', 'r');
// the destination file
$file_stream_destination = fopen(__DIR__ . '/test2.txt', 'w');
// while the end of the file is not reached
while (true) {
// read the file
$file_line = fgets($file_stream_source);
// if the end of the file is reached
if (!$file_line) {
// break the loop
break;
}
// write the file to the destination file
fputs($file_stream_destination, $file_line);
}
// close the source file
fclose($file_stream_destination);
// close the destination file
fclose($file_stream_source);
输出。
# contents of the test.txt file equal to the test2.txt file
当你执行上述脚本时,你会发现文件test.txt 的内容被写入文件test2.txt 。
这在上面的脚本中是通过使用fputs() 函数实现的。fputs() 函数将文件流作为第一个参数,将文件内容作为第二个参数。
我们首先使用fopen() 函数打开源文件。fopen() 函数接收两个参数,第一个是文件路径,第二个是模式。
接下来,我们使用while(true) 循环来检查是否到达了文件的末端。我们在循环内使用fgets() 函数读取每个文件行。
但是,我们也要检查是否到达了该行的末尾。如果是,我们就中断循环。否则,我们使用fputs() 函数将该行写到目标文件中。
最后,我们使用fclose() 函数关闭源文件和目标文件。
总结
在这篇文章中,我们已经广泛地介绍了流的概念以及如何在PHP中使用它们。
我希望这篇文章能帮助你在这些概念上打下坚实的基础,以帮助你在PHP上打下坚实的基础。