Я создаю защищенную систему загрузки файлов для сайта электронной коммерции. Я использую PHP для проверки подлинности того, что пользователь вошел в систему и владеет продуктом до его загрузки. Я использую пример, предоставленный PHP.net manual, но столкнулся с ошибкой, обслуживающей файлы PDF и PNG.PHP force download, не отправляя полные двоичные файлы
Он работал в какой-то момент, во время разработки. Теперь, когда мы поехали вживую, он, кажется, сломался ... К счастью, на данный момент веб-сайт не работает в полную силу, так что сейчас это не огромная проблема.
Что происходит:
Вы посещаете загрузки URL. Вы считаетесь владельцем продукта, и загрузка начинается. Все выглядит нормально, просматривая заголовки, все выглядит нормально. Заголовок указывает, что длина содержимого равна «229542» (224,16 КБ), что выглядит нормально.
Проблема:
После завершения загрузки, размер файла составляет всего 222 байт . Ошибок не отображается, и никакие ошибки/предупреждения/уведомления PHP не отправляются в файл или браузер. Это как если бы PHP прекращался, но без каких-либо предупреждений. Даже если я включу отладку, я не вижу никаких предупреждений.
Исходный файл looks like this (в Notepad ++, это PDF так это двоичный)
Когда загружен, он looks like this (только 7 линий, по сравнению с 2554)
Мое предположение:
Я довольно уверен, что проблема связана с заголовком. Может быть, вызвано плагином? Это проявляется в сетевой консоли в Chrome:
Response Headers:
Ниже приведены заголовки ответа. «Связь: закрытие» касается меня. Я не отправляю этот заголовок. Я предполагаю, что он отправлен командой exit
.
Access-Control-Allow-Origin:*
Cache-Control:must-revalidate, post-check=0, pre-check=0
Connection:close
Content-Description:File Transfer
Content-Disposition:attachment; filename="workbook.pdf"
Content-Length:229542
Content-Transfer-Encoding:binary
Content-Type:application/pdf
Date:Tue, 03 Sep 2013 21:16:14 GMT
Expires:0
Pragma:public
Server:Apache
X-Powered-By:PleskLin
Я также попытался:
Включение PHP отладки, чтобы получить какой-то ошибки/предупреждения, но я не получаю ничего полезного в браузере или в загруженном файле источника ,
Вывод в браузер, а не потоковая передача. Файл по-прежнему прерван, я ожидаю, что PDF-файл попытается отобразить в PDF-браузере браузера, но он даже не пытается. Просто белая страница с кучей неизвестных символов.
Использование + радиоканал режим чтения, используя
fopen($file['file'], 'rb'); echo fread($fh, filesize($file['file'])); fclose($fh);
Использование
ignore_user_abort(true)
иset_time_limit(0)
никакого эффекта (также пытался set_time_limit (10000) только для в случае, до сих пор ничего)Отправка
.txt
файла. Это сработало. Я пробовал с помощью простого 5-байтового текстового файла и снова с файлом 86.3kb. И, по всей видимости вышли так же, как они вошли. Так должно быть связано с бинарными файлами ...
/* --- This is what the $file variable looks like:
$file = array(
[file] => /var/www/vhosts/my-website/uploads/workbook.pdf
[type] => application/pdf
[filesize] => 229542
[filename] => workbook.pdf
[upload_date] => 1377278303
);
*/
// Stream the file to the user
if (file_exists($file['file'])) {
header_remove(); // Remove any previously set header
header('Content-Description: File Transfer');
header('Content-Type: ' . $file['type']);
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $filesize);
ob_clean();
flush();
readfile($file['file']);
exit;
}
Возможно, вы должны делать 'readfile ($ file);', а не 'readfile ($ file ['file']);' Я видел, как это происходит раньше. –
В этом случае $ file - это просто массив. $ file ['file'] (как-то запутанно) содержит фактическое имя файла. Я попытался использовать 'fopen' и используя дескриптор файла с' readfile', но я все еще получаю ту же проблему. –
И вы пробовали 'readfile ($ filename);'? –