您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    如何在不会招致效劳器宕机的状况下,用PHP读取大文件
    时间:2017-12-05 21:10 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    作为PHP开发人员,我们并不常常需求担忧内存管理。PHP 引擎在我们背后做了很好的清算任务,短期执行上下文的 Web 效劳器模型意味着即使是最潦草的代码也不会形成耐久的影响。

    很少状况下我们能够需求走出这个温馨的中央 —— 比如当我们试图在一个大型项目上运转 Composer 来创立我们可以创立的最小的 VPS 时,或许当我们需求在一个异样小的效劳器上读取大文件时。

    如何在不会招致效劳器宕机的状况下,用PHP读取大文件

    前面的成绩就是我们将在本教程中深化讨论的。

    在 GitHub 上可以找到本教程的源码。

    权衡成功的标准

    确保我们对代码停止任何改良的独一办法是测试一个不好的状况,然后将我们修复之后的测量与另一个停止比较。换句话说,除非我们知道“处置方案”对我们有多大的协助(假设有的话),否则我们不知道它能否真的是一个处置方案。

    这里有两个我们可以关系的权衡标准。首先是CPU运用率。我们要处置的进程有多快或多慢?第二是内存运用状况。脚本执行时需求多少内存?这两个通常是成正比的 - 这意味着我们可以以CPU运用率为代价来降低内存运用,反之亦然。

    在一个异步执行模型(如多进程或多线程的PHP运用顺序)中,CPU和内存的运用率是很重要的考量要素。在传统的PHP架构中,当任何一个值到达效劳器的极限时,这些通常都会成为成绩。

    测量PHP内的CPU运用率是不实在践的。假设这是你要关注的范围,请思索在Ubuntu或MacOS上运用相似top的工具。关于Windows,请思索运用Linux子系统,以便在Ubuntu中运用top。

    为了本教程的目的,我们将测量内存运用状况。我们将看看在“传统”的脚本中运用了多少内存。我们将执行一些优化策略并对其停止度量。最后,我希望你可以做出一个有阅历的选择。

    我们查看内存运用多少的办法是:

    // formatBytes is taken from the php.net documentation 

     

    memory_get_peak_usage(); 

     

    function formatBytes($bytes, $precision = 2) { 

        $units = array("b""kb""mb""gb""tb"); 

     

        $bytes = max($bytes, 0); 

        $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 

        $pow = min($pow, count($units) - 1); 

     

        $bytes /= (1 << (10 * $pow)); 

     

        return round($bytes, $precision) . " " . $units[$pow]; 

    我们将在脚本的最后运用这些函数,以便我们可以看到哪个脚本一次运用最大的内存。

    我们的选择是什么?

    这里有很多办法可以有效地读取文件。但是也有两种我们能够运用它们的状况。我们想要同时读取和处置一切数据,输入处置过的数据或依据我们所读取的内容执行其他操作。我们也能够想要转换一个数据流,而不需求真正拜访的数据。

    让我们想象一下,关于第一种状况,我们希望读取一个文件,并且每10,000行创立一个独立排队的处置作业。我们需求在内存中保留至少10000行,并将它们传递给排队的任务管理器(无论采取何种方式)。

    关于第二种状况,我们假定我们想要紧缩一个特别大的API照应的内容。我们不在乎它的内容是什么,但我们需求确保它是以紧缩方式备份的。

    在这两种状况下,假设我们需求读取大文件,首先,我们需求知道数据是什么。第二,我们并不在乎数据是什么。让我们来探求这些选择吧...

    逐行读取文件

    有许多操作文件的函数,我们把部分结合到一个复杂的文件阅读器中(封装为一个办法):

    // from memory.php 

     

    function formatBytes($bytes, $precision = 2) { 

        $units = array("b""kb""mb""gb""tb"); 

     

        $bytes = max($bytes, 0); 

        $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); 

        $pow = min($pow, count($units) - 1); 

     

        $bytes /= (1 << (10 * $pow)); 

     

    (责任编辑:admin)