PHP:如何优化通过CSV的循环并根据列中的值将行写入文件中

问题描述 投票:1回答:1

我有下面的代码,它需要一个$filename并在其中循环。如果第9列位于值数组中(此处未显示),则将其忽略。

否则,我将该行写到名称基于第三列的文件中。

if (($handle = fopen($filename, "r")) !== FALSE) {
    fgetcsv($handle);
    while (($line = fgetcsv($handle, 2000, ";")) !== FALSE) {
        if (!in_array($line[8], $exclude)) {
            $d = str_replace('/','',$line[2]);
            $f = fopen($base.$d.'.csv', "a");
            fputcsv($f, $line);
            fclose($f);
            unset($line);
        }
    }
    fclose($handle);
}

这很好。但是,它非常慢。我有200Mb的CSV正在循环通过。

我的问题是它是否可以优化和/或我是否在做可悲的事情?

谢谢

php arrays fopen fgetcsv fputcsv
1个回答
1
投票

打开和关闭文件总是很昂贵的操作,因此减少此操作将有助于您为输入文件中的每一行打开和关闭文件。

此代码使文件数组保持打开状态,并每次检查它是否已打开,如果已打开,则使用存储的句柄,如果未打开则存储新的句柄。然后在代码末尾,它循环遍历所有打开的文件并关闭所有文件...

if (($handle = fopen($filename, "r")) !== FALSE) {
    $outHandles = [];
    fgetcsv($handle);
    while (($line = fgetcsv($handle, 2000, ";")) !== FALSE) {
        if (!in_array($line[8], $exclude)) {
            $d = str_replace('/','',$line[2]);
            if ( isset($outHandles[$d]) )   {
                $f = $outHandles[$d];
            }
            else    {
                $f = fopen($base.$d.'.csv', "a");
                $outHandles[$d] = $f;
            }
            fputcsv($f, $line);
            unset($line);
        }
    }
    fclose($handle);
    foreach ( $outHandles as $file )    {
        fclose($file);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.