我正在使用带有IRON IO队列的flysystem,我正在尝试运行一个数据库查询,这个数据将占用约180万条记录,而且当时正在执行5000条记录。以下是我收到的文件大小为50+ MB的错误消息:
PHP Fatal error: Allowed memory size of ########## bytes exhausted
以下是我要采取的步骤:
1)获取数据
2)将其转换为适当的CSV字符串(即implode(',', $dataArray) . "\r\n"
)
3)从服务器获取文件(在本例中为S3)
4)阅读那些文件'内容并将此新字符串附加到其中并将该内容重新写入S3文件
以下简要介绍了我的代码:
public function fire($job, $data)
{
// First set the headers and write the initial file to server
$this->filesystem->write($this->filename, implode(',', $this->setHeaders($parameters)) . "\r\n", [
'visibility' => 'public',
'mimetype' => 'text/csv',
]);
// Loop to get new sets of data
$offset = 0;
while ($this->exportResult) {
$this->exportResult = $this->getData($parameters, $offset);
if ($this->exportResult) {
$this->writeToFile($this->exportResult);
$offset += 5000;
}
}
}
private function writeToFile($contentToBeAdded = '')
{
$content = $this->filesystem->read($this->filename);
// Append new data
$content .= $contentToBeAdded;
$this->filesystem->update($this->filename, $content, [
'visibility' => 'public'
]);
}
我认为这不是最有效的吗?我将离开这些文档: PHPLeague Flysystem
如果有人能指出我更合适的方向,那就太棒了!
答案 0 :(得分:1)
如果您正在使用S3,我将直接使用AWS SDK for PHP来解决此特定问题。使用SDK的S3 streamwrapper实际上非常容易追加到文件,并且不会强迫您将整个文件读入内存。
$s3 = \Aws\S3\S3Client::factory($clientConfig);
$s3->registerStreamWrapper();
$appendHandle = fopen("s3://{$bucket}/{$key}", 'a');
fwrite($appendHandle, $data);
fclose($appendHandle);
答案 1 :(得分:1)
Flysystem支持读/写/更新流
请检查最新的API https://flysystem.thephpleague.com/api/
$stream = fopen('/path/to/database.backup', 'r+');
$filesystem->writeStream('backups/'.strftime('%G-%m-%d').'.backup', $stream);
// Using write you can also directly set the visibility
$filesystem->writeStream('backups/'.strftime('%G-%m-%d').'.backup', $stream, [
'visibility' => AdapterInterface::VISIBILITY_PRIVATE
]);
if (is_resource($stream)) {
fclose($stream);
}
// Or update a file with stream contents
$filesystem->updateStream('backups/'.strftime('%G-%m-%d').'.backup', $stream);
// Retrieve a read-stream
$stream = $filesystem->readStream('something/is/here.ext');
$contents = stream_get_contents($stream);
fclose($stream);
// Create or overwrite using a stream.
$putStream = tmpfile();
fwrite($putStream, $contents);
rewind($putStream);
$filesystem->putStream('somewhere/here.txt', $putStream);
if (is_resource($putStream)) {
fclose($putStream);
}