PHP加载大型csv文件 - 内存问题

时间:2015-10-19 13:46:11

标签: php memory

我有以下代码

$file="postcodes.csv";
$csv= file_get_contents($file);
$array = array_map("str_getcsv", explode("\n", $csv));
$json = json_encode($array);
print_r($json);

postcodes.csv的大小为603MB,因此是一个大文件。

在php.ini中,如果我有

  

memory_limit的= 1024M

我收到错误

  

致命错误:允许的内存大小为1073741824字节(已尝试   在...中分配256个字节)

如果我将内存限制增加到2056,我会收到错误

  

致命错误:内存不足(已分配1919680512)(试图分配   36个字节)...

如果我将其更改为-1,则类似。

那么如何在没有内存问题的情况下加载此csv文件?

由于

4 个答案:

答案 0 :(得分:2)

您可以逐行阅读文件。

例如,

$file="postcodes.csv";
$array = array();
if (($handle = fopen($file, "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $array[]=$data;
    }
    fclose($handle);
}
$json = json_encode($array);
print_r($json);

但是如果你真的有很多数据并且你的数组太大,那么内存问题仍然会发生

答案 1 :(得分:1)

如果您正在阅读一个大文件,我建议使用文件指针和fgetcsv()函数并逐行循环而不是加载整个文件。

此外,新行不一定意味着CSV行的结尾,explode("\n", $csv)可能会给您带来一些不必要的结果......使用fgetcsv()

会更安全

答案 2 :(得分:1)

不是将整个文件放入变量,而是将其解析为换行符,然后对每个数组元素执行str_getcsv

根据您的目标,一个完整的json包含每行的所有值或多个json字符串,每个csv行一个。

$h = fopen("postcodes.csv",);

if ($h !== FALSE) {
    $str ='';
    while (($data = fgetcsv($handle)) !== FALSE) {

        $str .= json_encode($data); // add each json string to a string variable, save later
        // or
        $array[]=$data;     
    }
}
fclose($h);

$finalJsonString = json_encode($array);

我不建议你print_r这个大小的整个arrayjson对象,因为它很难跟进。

答案 3 :(得分:1)

答案很简单,你需要在php.ini中增加memory_limit,因为文件有603MB,但在代码中使用所有这个函数会在json数据的内存中创建一些结构,这超过603MB。 Alernativley你可以优化内存使用情况改变代码,但你的问题是如何增加内存限制。