Php 读取文件内容的最快方式

Php 读取文件内容的最快方式,php,file-io,Php,File Io,好的,我正在寻找一种最快的方法,通过php在服务器上使用文件路径读取文件的所有内容,而且这些文件可能非常大。因此,尽可能快地对其进行只读是非常重要的 逐行阅读是否比阅读全部内容快?虽然,我记得读过一些,阅读整个内容可能会产生巨大文件的错误。这是真的吗?你可以用 示例: $homepage = file_get_contents('http://www.example.com/'); echo $homepage; 如果要将文件的全部内容加载到PHP变量,最简单(可能也是最快)的方法是 但是,如

好的,我正在寻找一种最快的方法,通过php在服务器上使用文件路径读取文件的所有内容,而且这些文件可能非常大。因此,尽可能快地对其进行只读是非常重要的

逐行阅读是否比阅读全部内容快?虽然,我记得读过一些,阅读整个内容可能会产生巨大文件的错误。这是真的吗?

你可以用

示例:

$homepage = file_get_contents('http://www.example.com/');
echo $homepage;

如果要将文件的全部内容加载到PHP变量,最简单(可能也是最快)的方法是

但是,如果您使用的是大文件,那么将整个文件加载到内存中可能不是一个好主意:您可能最终会出现错误,因为PHP不允许您的脚本使用超过(通常)几兆字节的内存



因此,即使这不是最快的解决方案,也可能需要逐行读取文件(++),并在不将整个文件加载到内存的情况下动态处理这些行…

一次性读取整个文件会更快

但是巨大的文件可能会消耗掉你所有的内存并引起问题。那么你最安全的办法就是逐行阅读

$file_handle = fopen("myfile", "r");
while (!feof($file_handle)) {
   $line = fgets($file_handle);
   echo $line;
}
fclose($file_handle);
  • 打开文件并将其存储在
    $file\u handle
    中,作为对文件本身的引用
  • 检查您是否已经在文件末尾
  • 继续阅读文件,直到最后,在阅读时打印每一行
  • 关闭文件
  • file\u get\u contents()
    是在PHP中读取文件的最优化的方式,但是-因为您在内存中读取文件,所以您总是受限于可用的内存量

    如果您拥有正确的权限,但仍会受到系统可用内存量的限制,则可以发出
    ini\u集('memory\u limit',-1)
    ,这对于所有编程语言都是通用的

    唯一的解决方案是分块读取文件,因为您可以使用
    文件获取内容()
    和第四和第五个参数(
    $offset
    $maxlen
    -在字节中指定):

    下面是一个示例,我使用此技术为大型下载文件提供服务:

    public function Download($path, $speed = null)
    {
        if (is_file($path) === true)
        {
            set_time_limit(0);
    
            while (ob_get_level() > 0)
            {
                ob_end_clean();
            }
    
            $size = sprintf('%u', filesize($path));
            $speed = (is_int($speed) === true) ? $size : intval($speed) * 1024;
    
            header('Expires: 0');
            header('Pragma: public');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
            header('Content-Type: application/octet-stream');
            header('Content-Length: ' . $size);
            header('Content-Disposition: attachment; filename="' . basename($path) . '"');
            header('Content-Transfer-Encoding: binary');
    
            for ($i = 0; $i <= $size; $i = $i + $speed)
            {
                ph()->HTTP->Flush(file_get_contents($path, false, null, $i, $speed));
                ph()->HTTP->Sleep(1);
            }
    
            exit();
        }
    
        return false;
    }
    
    使用哪种技术实际上取决于您尝试执行的操作(正如您在SQL导入函数和下载函数中看到的),但是您必须始终以块的形式读取数据

    使用fpassthru或readfile。 两者都使用不断增大的文件大小的恒定内存


    如果您不担心内存和文件大小

    $lines = file($path);
    
    $lines是文件的数组。

    您可以尝试cURL()

    尽管你可能想检查一下,但它也有它的局限性

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://example.com/");
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec ($ch); // Whole Page As String
    curl_close ($ch);
    

    这对任何大小的文件都有效?不管文件大小有多大?@SoLoGHoST:不,它也有内存限制。哦,好吧,这不是我想要的。无论如何,谢谢。@SoLoGHoST:作为替代,您可以逐行使用
    fgets
    函数。另外,
    file\u get\u contents
    函数在大多数情况下都可以正常工作。只有当指令
    allow\u url\u fopen
    设置为
    On
    php.ini
    文件中的
    1
    时,上面的代码才可以工作。使用
    SESSIONS
    存储此信息是一个好主意,因此我们不必继续打开文件,如果已经打开过一次?首先,会话(默认情况下)存储到文件中;;;然后,您不应该将大数据放入会话(因为每个请求都是序列化/非序列化的);;;将此存储到会话将复制数据:每个用户有不同的会话;;;因此,我想说,不,将此存储到会话不是一个好主意。因此,抱歉,如果我不理解这一点,您认为在逐行读取文件后将其作为序列化字符串存储到数据库中,而不是通过取消序列化将其打开会更好吗?只要您尝试将整个文件加载到内存中(无论是从文件、从会话还是从数据库),如果数据太长,将消耗大量内存;;这就是为什么不使用太多内存的最佳解决方案是逐行读取文件,读取时直接处理每一行,而不是将整个数据存储到内存中。(参考)这个问题有点老,但为了将来参考,我在不久前发现了它。它对几种PHP读取方法进行了基准测试,并得出结论,
    readfile()
    fpassthru
    是最快的,只要您不需要对该文件进行任何处理(即,文件中没有需要处理的PHP脚本)。这里有几个重要的PHP方法来获取内容,并在启动函数之前使用
    echo microtime
    对它们进行测试,然后在函数之后再次执行
    echo microtime
    并查看结果:我相信这只是一个预分割(/\r?\n?/,file\u get\u contents())是否有理由将每个单词的第一个字母大写?如果文件中有很短的行,一次读取一行可能不是很理想。以特定大小的块进行读取可能会更好
    $lines = file($path);
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://example.com/");
    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec ($ch); // Whole Page As String
    curl_close ($ch);
    
    foreach (new SplFileObject($filepath) as $lineNumber => $lineContent) {
    
        echo $lineNumber."==>".$lineContent;  
        //process your operations here
    }