0

我有一个 260k 行的 csv 文件,它有两列。我已经使用 fgetcsv 读取了 csv 文件,并且有一个 while 循环读取文件中的每一行。在循环中,我试图将第二列中的值添加到数组中。

当我将行添加到数组中时,我的 PHP 冻结并且没有完成。我已经完成调试并且值被添加到数组中,所以我知道添加到数组和 while 循环可以工作,但我不知道它为什么会冻结。

如果我删除该行,while 循环将完成 260k 行,然后处理文件的其余部分。

这是我的代码:

$amountRecords = 0;
$totalValue = 0;
$valueArray = array();

// reads in csv file
$handle = fopen('Task1-DataForMeanMedianMode.csv', 'r');
// to skip the header names/values
fgetcsv($handle);

// creates array containing variables from csv file
while(($row = fgetcsv($handle, "\r")) != FALSE)
{

    /*
    echo "ROW CONTAINS: ";
    var_dump($row[1]);
    echo "<br />";
    */

    $valueArray[] = $row[1];

    /*
    echo "VALUEARRAY NOW CONTAINS: ";
    var_dump($valueArray);
    echo "<br />";
    */

    $totalValue = $totalValue + $row[1];
    $amountRecords++;

}

以及 csv 文件样本:

ID,Value
1,243.00
2,243.00
3,243.00
4,243.00
5,123.11
6,243.00
7,180.00
8,55.00
9,243.00
10,55.00
4

4 回答 4

1

对于内存不足错误,有两种通用方法。像往常一样,您可以选择简单但错误和困难但正确的选择。简单但错误的解决方案是将内存限制增加到适当的水平:

ini_set('memory_limit', '64M');

更好(虽然更难)的解决方案是重新设计您的算法以不需要太多内存。这显然是更可持续和更稳健的方法。要正确执行此操作,您将需要评估您需要对正在构建的阵列做什么。例如,我编写了将行导入数据库的类似脚本。我没有构建一个巨大的数组然后插入,而是分批进行,在那里我构建了一个 50-100 行的数组,然后插入这些数组并清除数组(释放内存以供重复使用)。

伪代码:

for(each row in file) {
  $rows_cache[] = $row[1];
  if(count($rows_cache) >= 50) {
    insert_these($rows_cache);
    $rows_cache = array();
  }
}
于 2012-08-19T19:48:34.440 回答
0

为什么不掉线:

$totalValue = $totalValue + $row[1];

从循环内部,而是使用:

$totalValue = array_sum($valueArray);

完成循环后

于 2012-08-19T17:12:01.870 回答
0

不是真正的问题,而是

while(($row = fgetcsv($handle, "\r")) != FALSE)

可以改写为

while($row = fgetcsv(...)) 

反而。不需要显式的错误检查——如果 fgetcsv 返回错误,while 循环无论如何都会终止。此外,这个版本更易读,而且没有那么冒险。如果你忘记了()fget 部分,你将做相当于$row = (fgetcsv() != false)并简单地获得一个布尔值。

于 2012-08-19T17:14:02.587 回答
0

您的第一行是字符串,也许尝试添加

while(($row = fgetcsv($handle, "\r")) != FALSE)
{

    if(is_numeric($row[1]))
    { 
        $valueArray[] = $row[1];

        $totalValue = $totalValue + $row[1];
        $amountRecords++;
    }
}
于 2012-08-19T16:30:24.633 回答