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

PHP加载大型csv文件-内存问题,php,memory,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中,如果我有 内存限制=1024M 我得到了错误 致命错误:已用尽1073741824字节的允

我有以下代码

$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中,如果我有

内存限制=1024M

我得到了错误

致命错误:已用尽1073741824字节的允许内存大小(已尝试 要在中分配256个字节,请执行以下操作

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

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

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

那么,如何在没有内存问题的情况下加载这个csv文件呢


谢谢

您可以逐行阅读您的文件

比如说,

$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);

但是,如果您有大量数据且数组太大,内存问题仍然可能发生。如果您正在读取一个大文件,我建议使用文件指针和
fgetcsv()
函数并逐行循环,而不是加载整个文件


另外,新行不一定意味着CSV行的结尾,
explode(“\n”,$CSV)
可能会给您一些不需要的结果。。。更安全的做法是使用
fgetcsv()

而不是将完整文件放入变量中,对其进行换行分析,然后对每个数组元素执行
stru getcsv

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

$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);

我不建议您
打印整个
数组
json
这样大小的对象,因为它很难理解。

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

除非您实际上需要一次在内存中处理所有行(这是罕见的),否则我建议将它们分部分处理-最坏的情况是“读取一行,处理它,输出,重复”。我同意上述观点,但为了分析这一点:PHP是否在读取时将每个字符转换为您的本机CPU字长?如果是这样,根据您的体系结构,尝试将您的
内存\u限制
增加到输入文件中至少4*或8*个字符的数量,并查看这是否有帮助。免责声明:我还没有用PHP读取文件。第2-4行的基本意思是:一次至少三次在内存中保存所有~600 MB的数据(作为字符串、数组、JSON字符串)。这实际上是一个很好的例子,说明了如何避免做那样的事情。对不起。:)