【发布时间】:2020-11-07 08:52:16
【问题描述】:
在我的 Laravel 应用程序的计划任务中,我正在外部 FTP 服务器上读取几个大的 gzip 压缩 CSV 文件,从 80mb 到 4gb 不等,其中包含我根据产品属性存储在我的数据库中的产品。
我循环浏览我想要导入的产品提要列表,但每次都返回致命错误:“允许的内存大小为 536870912 字节已用尽”。我可以将fgetcsv 函数的长度参数从1000 提高到100000,这解决了较小文件(
是否有一种解决方案可以让我下载或解压缩 .csv.gz 文件、读取行(批量或逐个)并将产品插入我的数据库而不会耗尽内存?
$feeds = [
"feed_baby-mother-child.csv.gz",
"feed_computer-games.csv.gz",
"feed_general-books.csv.gz",
"feed_toys.csv.gz",
];
foreach ($feeds as $feed) {
$importedProducts = array();
$importedFeedProducts = 0;
$csvfile = 'compress.zlib://ftp://' . config('app.ftp_username') . ':' . config('app.ftp_password') . '@' . config('app.ftp_host') . '/' . $feed;
if (($handle = fopen($csvfile, "r")) !== FALSE) {
$row = 1;
$header = fgetcsv($handle, 1, "|");
while (($data = fgetcsv($handle, 1000, "|")) !== FALSE) {
if($row == 1 || array(null) !== $data){ $row++; continue; }
$product = array_combine($header, $data);
$importedProducts[] = $product;
}
fclose($handle);
} else {
echo 'Failed to open: ' . $feed . PHP_EOL;
continue;
}
// start inserting products into the database below here
}
【问题讨论】:
-
该长度参数与单行的最大长度有关,但与文件的总大小无关。该文件中是否有超过这么大长度的行?
-
我修改了我最初的答案,有一些示例......