首页 > 解决方案 > 生成大集合数据到文件,优化资源,代码可复用

问题描述

我必须生成大量数据到文件。但是,我将这些数据存储在数组中,然后放入文件中。这个合乎逻辑的运行,但我想以 2 个标准做出回应:

例子 :

class A {

public function getArrayOfData() {
    $t_header[] = [
        'col1',
        'col2',
        ...
        'colN',
    ];

    $t_body = [];

    foreach($this->objects as $object) {
        $t_oneLine = [];

        $t_oneLine[] = $object->method1($param1);
        $t_oneLine[] = $object->method2();
        ...
        $t_oneLine[] = ('toto' == $object->methodN() ? 'ok', 'failed');

        $t_body[] = $t_oneLine;
    }

    return array_merge($t_header, $t_body);
}

}


# main
$a1 = new A();
...
$o = $a1->getArrayOfData();
transformAndWriteToCsv($o);

... (i can do many processes with $o variable if i want)

优化资源:

在这个例子中,我可以直接注入文件(并使用 php://temp 定义一个限制(2MB?)来解决这个问题。但是,我们在生成数据和使用生成的数据之间获得了紧密耦合。

提前感谢您的任何建议,甚至是提供有关我的主题的更多信息的问题。

标签: php

解决方案


我会尽量给你一个一般性的回答你的问题。在处理具有数百万行的大型数据集时,您必须解决 php 中的三个主要问题:内存使用、cpu 使用和执行时间。如您所知,将数百万个项目加载到 ram 中会导致您的应用程序崩溃。最好是在 php 中使用 yield 运算符。请参见下面的片段:

function process() {
  foreach ($items as $item) {
     yield $item;
  }
}

foreach(processItem() as $item) {
 // write csv line
}

要解决 ram 问题,您将使用游标从 db/file/etc 获取数据。(所以你只有一个项目,或者你也可以分块数据)。

下一个问题是执行时间:如果您有大量数据,您的脚本可能永远不会完成。PHP有一个最大值。执行时间,因此它将在 30 秒后停止(默认值)。当然,您可以增加限制,但这可能会影响其他用户使用您网站的体验。

cpu使用率:处理百万行也会增加cpu的使用率,也会影响其他用户的体验。如前所述,最好使用队列(beanstalk、rabbitmq 等)。您将通过一个作业来导出数据,并且在导出准备好时通知用户。

我希望现在一切都清楚了。


推荐阅读