Мое приложение должно передать обратно в браузер большой файл, то есть сервер удаленно. В настоящее время файл подается с локального сервера NodeJS.Стрим удаленный файл с PHP и Guzzle
Я использую образ диска VirtualBox размером 25 ГБ, чтобы быть уверенным, что он не сохраняется в памяти во время потоковой передачи. Это соответствующий код, который я борюсь с
require __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Stream\Stream;
use GuzzleHttp\Stream\LimitStream;
$client = new \GuzzleHttp\Client();
logger('==== START REQUEST ====');
$res = $client->request('GET', 'http://localhost:3002/', [
'on_headers' => function (\Psr\Http\Message\ResponseInterface $response) use ($res) {
$length = $response->getHeaderLine('Content-Length');
logger('Content length is: ' . $length);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="testfile.zip"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $length);
}
]);
$body = $res->getBody();
$read = 0;
while(!$body->eof()) {
logger("Reading chunk. " . $read);
$chunk = $body->read(8192);
$read += strlen($chunk);
echo $chunk;
}
logger('Read ' . $read . ' bytes');
logger("==== END REQUEST ====\n\n");
function logger($string) {
$myfile = fopen("log.txt", "a") or die ('Unable to open log file');
fwrite($myfile, "[" . date("d/m/Y H:i:s") . "] " . $string . "\n");
fclose($myfile);
}
Даже если $body = $res->getBody();
должен возвращать поток, он быстро полный диск с данными подкачки, а это означает, что он пытается сохранить в памяти, что перед потоковой передачей обратно в клиент, но это не ожидаемое поведение. Что мне не хватает?
подсказка 'stream => true' просто работала так, как я ожидал! Для наших целей, вероятно, этого достаточно (не так много клиентов, активных в то же время, мы ожидаем), но я буду внимательно читать связанный поток, чтобы я мог попробовать также «более безопасную» альтернативу. В любом случае, удивительный ответ! –