2013-09-03 9 views
1

Я создаю защищенную систему загрузки файлов для сайта электронной коммерции. Я использую 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:

enter image description here

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 

Я также попытался:

  1. Включение PHP отладки, чтобы получить какой-то ошибки/предупреждения, но я не получаю ничего полезного в браузере или в загруженном файле источника ,

  2. Вывод в браузер, а не потоковая передача. Файл по-прежнему прерван, я ожидаю, что PDF-файл попытается отобразить в PDF-браузере браузера, но он даже не пытается. Просто белая страница с кучей неизвестных символов.

  3. Использование + радиоканал режим чтения, используя fopen($file['file'], 'rb'); echo fread($fh, filesize($file['file'])); fclose($fh);

  4. Использование ignore_user_abort(true) и set_time_limit(0) никакого эффекта (также пытался set_time_limit (10000) только для в случае, до сих пор ничего)

  5. Отправка .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; 
} 
+0

Возможно, вы должны делать 'readfile ($ file);', а не 'readfile ($ file ['file']);' Я видел, как это происходит раньше. –

+0

В этом случае $ file - это просто массив. $ file ['file'] (как-то запутанно) содержит фактическое имя файла. Я попытался использовать 'fopen' и используя дескриптор файла с' readfile', но я все еще получаю ту же проблему. –

+0

И вы пробовали 'readfile ($ filename);'? –

ответ

1

Я знаю, что это старая нить, но у меня есть решение все здесь.

У вас есть сценарий где-то в вашем приложении, которое сжимает пробелы или другие символы.

ob_start("sanitize_output"); 

Это была проблема в одном сценарии, который я заметил. Если вы отключите скрипт сокращения буфера (называемый «sanitize_output» выше), ваш .pdf будет отображаться нормально. Эти дополнительные 2kb вы заметили, что были обрезаны, вероятно, из-за расстояния или вырезания ненужных символов.

0

Попробуйте этот код: Просто дайте $ file относительный путь к файлу и проверьте его.

<?php 
// your file to download 
$file = path/to/the/file; 

header("Expires: 0"); 
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); 
header("Cache-Control: no-store, no-cache, must-revalidate"); 
header("Cache-Control: post-check=0, pre-check=0", false); 
header("Pragma: no-cache"); 

$ext = pathinfo($file, PATHINFO_EXTENSION); 
$basename = pathinfo($file, PATHINFO_BASENAME); 

header("Content-type: application/".$ext); 
// tell file size 
header('Content-length: '.filesize($file)); 
// set file name 
header("Content-Disposition: attachment; filename=\"$basename\""); 
readfile($file); 
// Exit script. So that no useless data is output-ed. 
exit; 
?> 

Позвольте php вычислить размер и дату файла и прочее. Вполне возможно, что может произойти ошибка при подаче через массив.

Также в этом коде я использовал pathinfo для автоматического задания типа содержимого и имени файла.

 Смежные вопросы

  • Нет связанных вопросов^_^