如何避免在PHP数组中存储100万个元素

如何避免在PHP数组中存储100万个元素,php,arrays,memory,optimization,tls1.2,Php,Arrays,Memory,Optimization,Tls1.2,我正在用PHP解析一个1000000行的csv文件来恢复这些数据:IP地址、DNS、使用的密码套件。 为了知道某些DNS(具有多个邮件服务器)的服务器上是否使用了不同的密码套件,我必须在数组中存储一个对象,其中包含DNS名称、其服务器的IP地址列表以及其使用的密码套件列表。最后,我有一个1000个元素的数组。要了解在其服务器上具有不同密码套件配置的DNS的数量,我需要: foreach($this->allDNS as $dnsObject){ $res=0; if(count($

我正在用PHP解析一个1000000行的csv文件来恢复这些数据:IP地址、DNS、使用的密码套件。 为了知道某些DNS(具有多个邮件服务器)的服务器上是否使用了不同的密码套件,我必须在数组中存储一个对象,其中包含DNS名称、其服务器的IP地址列表以及其使用的密码套件列表。最后,我有一个1000个元素的数组。要了解在其服务器上具有不同密码套件配置的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文件并将其存储到数据库的教程,请参阅本教程

将处理后的数据(分别针对每一行)写入一个文件(或数据库)

FILE_APPEND将$parsingreult追加到文件内容的末尾

然后,您可以通过file\u get\u contents()或file()访问处理后的数据

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

您可以使用它一次读取和解析一行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文件所需的最小内存量。

使用数据库。它肯定会消耗内存,因为您正在内存中存储CSV数据。为什么不将csv导入数据库(可能在临时表中)并对该数据进行查询?好的,这将解决我的内存问题,但我如何处理计算时间问题?@Arthur,请问您如何“计算”数据?我使用索引数组解决了我的问题。实际上,在存储DNS对象之前,我检查了它是否已经在数组中。当我们在csv文件的末尾时,数组包含了更多thab 500000 DNS对象,对于每一个新行读取,我检查了所有数组,以知道它是否已经包含这个DNS。现在,我创建一个关联数组,将DNS存储为键,并将它在另一个数组中的索引作为值。例如:$mytab['toto.com']=9;因此,我可以通过直接转到正确的元素来修改另一个数组,而无需完全浏览表。
// 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);