phpleague flysystem读取和写入服务器上的大文件

时间:2014-09-24 15:13:13

标签: php file amazon-s3 queue

我正在使用带有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

如果有人能指出我更合适的方向,那就太棒了!

2 个答案:

答案 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);
}