【问题标题】:phpleague flysystem read and write to large file on serverphpleague flysystem读写服务器上的大文件
【发布时间】:2014-09-24 15:13:12
【问题描述】:

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

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

【问题讨论】:

  • 有没有办法使用 Flysystem 附加到文件中?否则我看不出你怎么能避免使用这么多内存。
  • @andy 不,它看起来不像。它们具有流功能,但我认为这与您必须读取文件以更新其内容的方式相同。

标签: php file amazon-s3 queue


【解决方案1】:

Flysystem 支持读/写/更新流

请查看最新APIhttps://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);
}

【讨论】:

    【解决方案2】:

    如果您使用的是 S3,我会直接使用 AWS SDK for PHP 来解决这个特殊问题。使用 SDK 的 S3 流包装器附加到文件实际上非常简单,并且不会强制您将整个文件读入内存。

    $s3 = \Aws\S3\S3Client::factory($clientConfig);
    $s3->registerStreamWrapper();
    
    $appendHandle = fopen("s3://{$bucket}/{$key}", 'a');
    fwrite($appendHandle, $data);
    fclose($appendHandle);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-25
      • 2012-06-19
      • 1970-01-01
      • 2012-04-21
      • 1970-01-01
      • 2017-08-04
      • 2011-10-30
      • 2016-10-29
      相关资源
      最近更新 更多