В настоящее время я использую внешние веб-службы SOAP, которые разрешают частичную загрузку / выгрузку двоичных файлов (должны разрешать файлы большего размера).Мне нужно разрешить конечному пользователю загружать файлы через браузер с моим приложением PHP.Обслуживание небольших файлов работает хорошо, но файлы размером более 25 МБ приводят к нехватке памяти на веб-сервере.
Я использую собственный клиент Soap PHP (без поддержки MTOM) и запрашиваю загрузку, отправив форму.В настоящее время создается впечатление, что веб-сервер пытается загрузить весь файл перед выводом чего-либо в браузер (например, приглашение «Загрузить» не отображается до тех пор, пока весь файл не будет обработан с помощью PHP).
Myметод выглядит примерно так (извините, если он неопрятный, я некоторое время решал эту проблему).
public function download()
{
$file_info_from_ws ... //Assume setup from $_REQUEST params
//Don't know if these are needed
gc_enable();
set_time_limit(0);
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
//File Info
$filesize = $file_info_from_ws->get_filesize();
$fileid = $file_info_from_ws->get_id();
$filename = $file_info_from_ws->get_name();
$offset = 0;
$chunksize = (1024 * 1024);
//Clear any previous data
ob_clean();
ob_start();
//Output headers
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $filesize);
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Accept-Ranges: bytes');
while($offset < $filesize)
{
$chunk = $this->dl_service()->download_chunked_file($fileid, $offset, $chunksize);
if($chunk)
{
//Immediately echo out the stream
$chunk->render();
$offset += $chunksize;
unset($chunk); //Shouldn't this trigger GC?
ob_flush();
}
}
ob_end_flush();
}
Так что мой главный вопрос: Что лучшеспособ вывода больших двоичных фрагментов из внешних ресурсов (веб-сервисы, БД и т. д.) через PHP для конечного пользователя?Желательно, не убивая слишком много памяти / ЦП.
Также мне интересно следующее:
Почему после первого вывода всплывающее окно «Загрузка» не появляется?
Почему память не освобождается после каждого цикла в методе about?