PHP:如何优化 CSV 循环并根据列中的值将一行写入文件
PHP: How to optimise looping through a CSV and writing a line to a file dependent on value in column
我有以下代码,它接受一个 $filename
并循环遍历它。如果第 9 列在值数组中(此处未显示),我将忽略它。
否则我将该行写入一个文件,该文件的名称基于第 3 列。
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 正在循环。
我的问题是它是否可以优化and/or我是否做错了什么可悲的事情?
谢谢
打开和关闭文件始终是一项开销很大的操作,因此当您为输入文件中的每一行打开和关闭一个文件时,减少它会有所帮助。
这段代码保持打开的文件数组,并且每次检查它是否已经打开,如果是就使用存储的句柄,如果没有打开并存储新的句柄。然后在代码的末尾循环遍历所有打开的文件并将它们全部关闭...
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);
}
}
我有以下代码,它接受一个 $filename
并循环遍历它。如果第 9 列在值数组中(此处未显示),我将忽略它。
否则我将该行写入一个文件,该文件的名称基于第 3 列。
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 正在循环。
我的问题是它是否可以优化and/or我是否做错了什么可悲的事情?
谢谢
打开和关闭文件始终是一项开销很大的操作,因此当您为输入文件中的每一行打开和关闭一个文件时,减少它会有所帮助。
这段代码保持打开的文件数组,并且每次检查它是否已经打开,如果是就使用存储的句柄,如果没有打开并存储新的句柄。然后在代码的末尾循环遍历所有打开的文件并将它们全部关闭...
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);
}
}