【问题标题】:How to avoid storing 1 million element in an array PHP如何避免在数组 PHP 中存储 100 万个元素
【发布时间】:2017-12-17 23:39:42
【问题描述】:

我正在用 PHP 解析一个 1 000 000 行的 csv 文件来恢复这些数据:IP 地址、DNS 、使用的密码套件。 为了知道某些 DNS(具有多个邮件服务器)是否在其服务器上使用了不同的密码套件,我必须在一个数组中存储一个包含 DNS 名称的对象、他的服务器的 IP 地址列表和列表他使用的密码套件。最后,我有一个包含 1 000 000 个元素的数组。要知道在其服务器上配置不同密码套件的 DNS 数量,我会这样做:

foreach($this->allDNS as $dnsObject){
$res=0;  
  if(count($dnsObject->getCiphers()) > 1){ //if it has several different config
    res++;
  }
return $res;
}  

问题:消耗太多内存,我无法在 1000000 行 csv 上运行我的代码(如果我不将这些数据存储在数组中,我会在 20 秒内解析这个 csv 文件......)。有没有办法绕过这个问题?

注意:我已经放了

ini_set('memory_limit', '-1');

但是这一行只是绕过了内存错误。

【问题讨论】:

  • 使用数据库。
  • 它肯定会消耗内存,因为您将孔 csv 数据存储在内存中。为什么不将 csv 导入数据库(可能在临时表中)并对该数据运行查询?

标签: php arrays memory optimization tls1.2


【解决方案1】:

保存所有这些 CSV 数据肯定会占用内存。

您的问题的一个合乎逻辑的解决方案是拥有一个可以存储所有这些数据的数据库。

您可以参考link 获取有关解析 CSV 文件并将其存储到数据库的教程。

【讨论】:

  • 好的,这将解决我的内存问题,但我该如何处理计算时间问题?
  • @Arthur,请问您如何“计算”数据?
  • 我使用索引数组解决了我的问题。事实上,在存储 DNS 对象之前,我检查了它是否已经在数组中。当我们在 csv 文件的末尾,数组包含超过 500 000 个 DNS 对象,并且每次读取新行时,我检查了所有数组以了解它是否已经包含此 DNS。现在,我创建了一个关联数组,将 DNS 作为键存储,并将其在另一个数组中的索引作为值存储。例如:$mytab['toto.com'] = 9;多亏了这一点,我可以通过直接转到正确的元素来修改另一个数组,而无需完全浏览表格。
【解决方案2】:

将处理后的数据(每行单独)写入一个文件(或数据库)

file_put_contents('data.txt', $parsingresult, FILE_APPEND);

FILE_APPEND 会将 $parsingresult 附加到文件内容的末尾。

然后就可以通过file_get_contents()或者file()来访问处理后的Data了。

无论如何。我认为,如果更频繁地需要,使用数据库和一些预处理将是最好的解决方案。

【讨论】:

    【解决方案3】:

    您可以使用fgetcsv() 一次读取和解析CSV 文件一行。保留您需要的数据并丢弃该行:

    // Store the useful data here
    $data = array();
    // Open the CSV file
    $fh = fopen('data.csv', 'r');
    // The first line probably contains the column names
    $header = fgetcsv($fh);
    // Read and parse one data line at a time
    while ($row = fgetcsv($fh)) {
        // Get the desired columns from $row
        // Use $header if the order or number of columns is not known in advance
        // Store the gathered info into $data
    }
    // Close the CSV file
    fclose($fh);
    

    这样,它使用解析 CSV 文件所需的最小内存量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-08
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      相关资源
      最近更新 更多