我有一个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
答案 0 :(得分:1)
出现内存不足错误,有两种常规方法。像往常一样,这些选择,你可以选择容易但错误和艰难但正确的选择。简单但错误的解决方案是将your memory limit提高到适当的水平:
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();
}
}
答案 1 :(得分:0)
你的第一行是字符串,也许可以尝试添加
while(($row = fgetcsv($handle, "\r")) != FALSE)
{
if(is_numeric($row[1]))
{
$valueArray[] = $row[1];
$totalValue = $totalValue + $row[1];
$amountRecords++;
}
}
答案 2 :(得分:0)
为什么不放弃这条线:
$totalValue = $totalValue + $row[1];
从你的循环内部,而不是使用:
$totalValue = array_sum($valueArray);
完成循环后
答案 3 :(得分:0)
不是问题,但是
while(($row = fgetcsv($handle, "\r")) != FALSE)
可以改写为
while($row = fgetcsv(...))
代替。不需要显式的错误检查 - 如果fgetcsv返回false,则while循环将终止。此外,这个版本更清晰,并没有风险。如果你忘记了fget部分周围的()
,那么你将完成相当于$row = (fgetcsv() != false)
并且只是得到一个布尔值。