使用Guzzle发送csv数据作为分块请求

时间:2016-05-11 09:33:41

标签: php rest http guzzle

我想将CSV数据上传到REST API(仅在某个特定点上除了CSV数据)。

CSV数据的来源是用户上传。上传的格式可以是CVS,ODS或XLSX电子表格数据。

当用户上传CSV文件时 - 我只是(简化):

$handle = \fopen($tempFile, 'r');
$client->post('/import', ['body' => $handle]);

这很有效,很容易解决。但是当用户上传例如XLSX时,我现在遍历第一张表中的行并使用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创建完整资源?我希望这是有道理的。也许这甚至不是优化......

1 个答案:

答案 0 :(得分:2)

根据GuzzleHttp文档,该库使用php流:

http://docs.guzzlephp.org/en/latest/psr7.html#body

因此,您可以为请求创建一个流,然后使用PSR7 \ StreamIntefrace类中的write方法逐行写入内容,如下所示:

https://github.com/php-fig/http-message/blob/master/src/StreamInterface.php#L115

BTW,正如您在Guzzle文档中所读到的那样,流本身使用php://temp就像您已经做的那样,只进行优化,如果流大于2MB,它将交换到保留超出内存的磁盘。 / p>