Php download script выводит поврежденный файл
Я создавал файл, загружающий класс для моей CMS в PHP, в то время, когда я заметил, что он выводит файлы в другом формате кодирования. Я пробовал с readfile, file_get_contents, fread, но все, похоже, делают то же самое. Это похоже на то, что связано с выходной буферизацией.
Пример файла изображения в формате png, который я загрузил с помощью script, похоже, работает после изменения кодировки с помощью блокнота ++ от UTF до ASCII
Это шаги, которые я сделал до сих пор:
$mime = http::get_file_mime();
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Transfer-Encoding: binary');
header('Transfer-Encoding: binary');
header('Content-Description: File Transfer');
header('Content-Encoding: chunked');
header('Connection: closed');
@readfile($this->file);
Я сделал fread:
$file = fopen($this->file,'r');
$read = fread($file,filesize($this->file));
print($read);
Я сделал file_get_contents();
$read = file_get_contents($this->file);
print($read);
Все эти шаги отправляют файл в диалоговое окно загрузки. Но он не выводит файл так, как есть. И это влияет на любой файл, который я пытаюсь загрузить с помощью script.
Что я делаю неправильно?
Ответы
Ответ 1
Попробуйте запустить ob_start()
в первую очередь в script, напишите материал, отредактируйте заголовки, а затем ob_flush()
и ob_clean()
, когда вы хотите, чтобы ваш контент отправлялся в пользовательский браузер.
Это сработало для меня..
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
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($file));
ob_clean();
flush();
readfile($file);
exit;
}
Надеюсь, что это поможет.
Ответ 2
Проблема заключается в заголовке Content-Disposition
. Этот заголовок на самом деле не является частью протокола HTTP, см. RFC 2616, 15.5 Проблемы с размещением контента
Content-Disposition не является частью стандарт HTTP, но поскольку он широко применяется, мы документируя его использование и риски для разработчиков.
И далее в разделе 19.5.1 Content-Disposition
Поле заголовка ответа Content-Disposition было предложено как означает, что исходный сервер предложит имя файла по умолчанию, если пользователь запрашивает, чтобы содержимое было сохранено в файл.
...
Пример:
Content-Disposition: attachment; filename="fname.ext"
Если этот заголовок используется в ответе с приложением/октетом- потоковый контент-тип, подразумеваемое предположение заключается в том, что пользовательский агент не должен отображать ответ, но непосредственно вводить ответ сохранения как... ".
Оставив этот заголовок, вы увидите содержимое отправленного файла.
Я тестировал это только с Firefox, поэтому другие веб-браузеры могут вести себя по-другому.