使用 Guzzle 将 csv 数据作为分块请求发送
Send csv data with Guzzle as a chunked request
我想将 CSV 数据上传到 REST API(仅在特定时间点除外 CSV 数据)。
CSV数据来源为用户上传。上传格式可以是CVS,ODS or XLSX spreadsheet data.
当用户上传 CSV 文件时 - 我只是这样做(简化):
$handle = \fopen($tempFile, 'r');
$client->post('/import', ['body' => $handle]);
这很有效,而且很容易做到。但是,例如,当用户上传 XLSX 时,我目前从第一行开始循环遍历行 sheet 并使用 fputcsv.
创建一个资源
use Box\Spout\Reader\ReaderFactory;
$reader = ReaderFactory::create('xlsx');
$reader->open($tempFile);
$handle = \fopen('php://temp', 'r+');
/** @var $reader \Box\Spout\Reader\XLSX\Reader */
foreach ($reader->getSheetIterator() as $sheet) {
/** @var $sheet \Box\Spout\Reader\XLSX\Sheet */
foreach ($sheet->getRowIterator() as $row) {
\fputcsv($handle, $row);
}
break;
}
$reader->close();
$client->post('/import', ['body' => $handle]);
我正在寻找一种在内存消耗和性能方面优化程序(XLSX 导入)的方法。
是否可以使用 guzzle 将 foreach ($sheet->getRowIterator() as $row)
中的请求作为分块请求发送,而无需先使用 fputcsv 创建完整资源?我希望这是有道理的。也许这甚至不是优化...
根据 GuzzleHttp 文档,该库使用 php 个流:
http://docs.guzzlephp.org/en/latest/psr7.html#body
因此您可以为您的请求创建一个流,然后使用 PSR7\StreamIntefrace class 中定义的 write
方法逐行将内容写入其中:
https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php#L115
顺便说一句,正如您在 Guzzle 文档中所读到的那样,流本身使用 php://temp
就像您已经在做的那样,只有优化,如果流大于 2MB,它将交换到磁盘以保留超出的内存.
我想将 CSV 数据上传到 REST API(仅在特定时间点除外 CSV 数据)。
CSV数据来源为用户上传。上传格式可以是CVS,ODS or XLSX spreadsheet data.
当用户上传 CSV 文件时 - 我只是这样做(简化):
$handle = \fopen($tempFile, 'r');
$client->post('/import', ['body' => $handle]);
这很有效,而且很容易做到。但是,例如,当用户上传 XLSX 时,我目前从第一行开始循环遍历行 sheet 并使用 fputcsv.
创建一个资源use Box\Spout\Reader\ReaderFactory;
$reader = ReaderFactory::create('xlsx');
$reader->open($tempFile);
$handle = \fopen('php://temp', 'r+');
/** @var $reader \Box\Spout\Reader\XLSX\Reader */
foreach ($reader->getSheetIterator() as $sheet) {
/** @var $sheet \Box\Spout\Reader\XLSX\Sheet */
foreach ($sheet->getRowIterator() as $row) {
\fputcsv($handle, $row);
}
break;
}
$reader->close();
$client->post('/import', ['body' => $handle]);
我正在寻找一种在内存消耗和性能方面优化程序(XLSX 导入)的方法。
是否可以使用 guzzle 将 foreach ($sheet->getRowIterator() as $row)
中的请求作为分块请求发送,而无需先使用 fputcsv 创建完整资源?我希望这是有道理的。也许这甚至不是优化...
根据 GuzzleHttp 文档,该库使用 php 个流:
http://docs.guzzlephp.org/en/latest/psr7.html#body
因此您可以为您的请求创建一个流,然后使用 PSR7\StreamIntefrace class 中定义的 write
方法逐行将内容写入其中:
https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php#L115
顺便说一句,正如您在 Guzzle 文档中所读到的那样,流本身使用 php://temp
就像您已经在做的那样,只有优化,如果流大于 2MB,它将交换到磁盘以保留超出的内存.