You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP脚本处理40000个CSV文件时内存耗尽错误求助

解决PHP处理大量CSV文件时的内存溢出问题

嘿,这个内存溢出问题其实很好搞定,我来帮你拆解下原因和解决方案:

问题根源

你的代码里有两个核心问题导致内存被耗尽:

  1. $data数组未在循环内重置:你没有在每次处理新文件时清空$data,导致这个数组会不断累积所有处理过的CSV内容。4万个文件下来,数组体积直接撑爆了PHP的内存限制。
  2. 一次性加载整个文件到内存:就算重置了数组,要是遇到大体积的CSV,把所有行都存进数组也会占用大量内存,同样可能触发溢出。

解决方案

方案1:修复现有代码的内存泄漏(适合小体积CSV)

只需要在每次循环开始时重置$data数组,确保每次只处理单个文件的内容:

<?php 
// Read the file 
for ($x = 0; $x <= 40000; $x++) { 
    // 每次循环重置数组,避免内存累积
    $data = [];
    $file = fopen('export'.$x.'.csv', 'r'); 
    // Iterate over it to get every line 
    while (($line = fgetcsv($file)) !== FALSE) { 
        // Store every line in an array 
        $data[] = $line; 
    } 
    fclose($file); 

    // Remove the first element from the stored array / first line of file being read 
    array_shift($data); 

    // Open file for writing 
    $file = fopen('export'.$x.'.csv', 'w'); 
    // Write remaining lines to file 
    foreach ($data as $fields) { 
        fputcsv($file, $fields); 
    } 
    fclose($file); 
    echo $x; 
} 
?>

方案2:流式处理(推荐,适配所有大小的CSV)

不需要把整个文件加载到内存,直接边读边写跳过第一行,内存占用极低,完全不会出现溢出问题:

<?php
for ($x = 0; $x <= 40000; $x++) {
    $inputFile = 'export'.$x.'.csv';
    $outputFile = 'export'.$x.'.tmp.csv'; // 先写临时文件,避免覆盖原文件出错

    // 检查文件是否存在
    if (!file_exists($inputFile)) {
        echo "文件 $inputFile 不存在,跳过\n";
        continue;
    }

    $inHandle = fopen($inputFile, 'r');
    $outHandle = fopen($outputFile, 'w');

    if (!$inHandle || !$outHandle) {
        echo "打开文件 $inputFile 失败,跳过\n";
        continue;
    }

    // 跳过第一行
    fgetcsv($inHandle);

    // 逐行读取并写入
    while (($line = fgetcsv($inHandle)) !== FALSE) {
        fputcsv($outHandle, $line);
    }

    fclose($inHandle);
    fclose($outHandle);

    // 替换原文件
    rename($outputFile, $inputFile);

    echo "处理完成:$x\n";
}
?>

额外小贴士

  • 别盲目调高内存限制:虽然可以通过ini_set('memory_limit', '256M')或修改php.ini增加内存,但这只是治标不治本,高效的代码才是长久之计。
  • 增加错误处理:处理大量文件时难免遇到文件不存在或无法打开的情况,加判断能让脚本更健壮。
  • 用glob遍历文件:如果文件名不是严格的export0.csv到export40000.csv,可以用glob('export*.csv')获取所有CSV文件,更灵活。

内容的提问来源于stack exchange,提问作者Nick lK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:47:51