phpleague flysystem чтение и запись в большой файл на сервере

Я использую систему flysystem с очередью IRON IO и пытаюсь выполнить запрос к базе данных, который будет содержать ~ 1,8 миллиона записей и 5000 одновременно. Вот сообщение об ошибке, которое я получаю с размером файла более 50 МБ:

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

Решение

Если вы работаете с S3, я бы использовал AWS SDK для PHP напрямую для решения этой конкретной проблемы. Присоединиться к файлу на самом деле очень просто, используя потоковую упаковку SDK S3, и не заставляет вас читать весь файл в память.

$s3 = \Aws\S3\S3Client::factory($clientConfig);
$s3->registerStreamWrapper();

$appendHandle = fopen("s3://{$bucket}/{$key}", 'a');
fwrite($appendHandle, $data);
fclose($appendHandle);
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);
}
1

По вопросам рекламы [email protected]