PHP 8中输入和输出流的入门方法

363 阅读3分钟

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上打下坚实的基础。