Я использую file_get_contents()
, чтобы прочитать файл размером более 7M (7 - 30M). И затем я повторяю это, чтобы позволить клиенту загрузить его.PHP: Почему я могу только загрузить 16 КБ (16624 байта) из файлов О 8М с помощью PHP echo?
Примечание: ссылки для скачивания этих файлов отсутствуют. Поэтому я должен прочитать его в PHP и сделать файл загрузки. Прочитать большой файл в памяти - это абсолютно неправильная идея. Лучший способ - сделать файл ссылкой для загрузки. Но не сейчас ... Coz файл создается другими, и у них нет плана переместить их на наши серверы облачных файлов. --- Поэтому я должен обрабатывать его с помощью PHP.
Есть что-то внятное. Он хорошо работает на моем личном контейнере для док-станции PHP7 (конфигурационный файл находится здесь: https://github.com/AarioAi/Conf)
Я могу скачать полный файл (возможно, 7.8M).
Но когда я нажимаю эти коды на другой сервер (PHP 5.5), который имеет почти те же конфигурации PHP и Nginx. Я могу загрузить только 16 КБ (16624В) этого файла.
Вот отладочная информация о бинарном файле 7.8m:
"HTTP_RANGE": null,
"Content-Length:": 7490833,
"md5": "aaefc8249e2a96574fa7b83e7bc168f0",
"fileSize": 7490833
Для того, чтобы проверить сегмент 16KB, является ли частью исходного файла. Я заполняю 16M-файл повторяющейся строкой «Hello, Aario». по сценарию оболочки. Затем я открываю загруженный сегмент 16 КБ с сервера PHP 5.5. Все они «Привет, Аари. Привет, Аари. .....»
Итак, 16 КБ определенно является сегментом исходного файла.
Вот отладочная информация о 16М «Здравствуй, Aario.»:
"HTTP_RANGE": null,
"Content-type": "application/force-download",
"Content-Length:": 16155228,
"md5": "5c919dd9d1049a59e7c2a8cb55a695a9",
"fileSize": 16155228
Я ничего не посылаем к ob_xxx, так что я думаю, что нет ничего плохого в output_buffering
конфигурации. Конфигурации PHP memory_limit
одинаковы на обоих серверах. И я также замечаю, что между файлами php-fpm.conf нет существенных различий.
Я думаю, это может быть перерыв. Я проверяю Nginx keepalive_timeout
на другом сервере (PHP 5.5), это 65
, который длиннее, чем на этом сервере (PHP 7).
Так вы могли бы дать мне несколько советов?
//---------------------------------------------------------------------
$length = (function_exists('mb_strlen') ? mb_strlen($content, '8bit') : strlen($content));
// it's just the sample to calculate Content-Length, actually,
// it needs be handled in the if (isset($_SERVER['HTTP_RANGE'])) {}
//----------------------------------------------------------------------
if (isset($_SERVER['HTTP_RANGE'])) {
header('Accept-Ranges: bytes');
//client sent us a multibyte range, can not hold this one for now
if (strpos($_SERVER['HTTP_RANGE'], ',') !== false) {
header("Content-Range: bytes $contentStart-$contentEnd/$fileSize");
....
....
}
if ($debug > 0) {
return [
'Content-type' => $contentType,
'Content-Length:' => $length,
'md5' => md5_file($file),
'fileSize' => $fileSize,
];
} else {
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Type: $contentType");
header('Content-Length: ' . $length);
header("Content-Disposition: attachment; filename=\"$fileName\"");
header('Content-Transfer-Encoding: binary');
$content = function_exists('mb_substr') ? mb_substr($content, $contentStart, $length) : substr($content, $contentStart, $length);
ob_start();
ob_end_clean();
echo $content;
exit(0);
}
ob_start() ... Вы можете Google это.И я хочу разрешить клиенту отправлять HTTP_RANGE. – AarioAi
Моя точка зрения: 'ob_start();', за которым сразу следует 'ob_end_clean();', ничего не делает. Вы можете оставить это, и результат будет таким же. Что касается 'HTTP_RANGE': мой код является коротким примером, вы можете его расширять в любом случае. –
Я пробовал fopen раньше, но это было так же, как 'echo $ content'. Прочитать большой файл в памяти - это абсолютно неверная идея. Лучший способ - сделать файл ссылкой на ссылку. Но не сейчас ... Coz файл создается другими, и у них нет плана переместить их на наши серверы облачных файлов. --- Поэтому я должен обрабатывать его с помощью PHP. Я пробовал fpassthru, это то же самое, только 16 КБ можно скачать с сервера PHP 5.5, а 7.8M из PHP7. – AarioAi