Я пытаюсь принудительно загружать файлы с моего веб-сервера с помощью PHP. Я не профессионал в PHP, но я просто не могу обойти проблему загрузки файлов в 0 байтах.
КОД:
$filename = "FILENAME..."; header("Content-type: $type"); header("Content-Disposition: attachment;filename=$filename"); header("Content-Transfer-Encoding: binary"); header('Pragma: no-cache'); header('Expires: 0'); set_time_limit(0); readfile($file);
Может ли кто-нибудь помочь? Благодарю.
Вы не проверяете, существует ли файл. Попробуйте использовать это:
$file = 'monkey.gif'; 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; }else { echo "File does not exists"; }
И посмотри, что получишь.
Следует также отметить, что это приводит к загрузке в виде потока октетов, простого двоичного файла. Некоторые браузеры будут пытаться понять точный тип файла. Если, например, вы отправляете GIF с заголовком Content-Type: application/octet-stream
, тогда браузер не может рассматривать его как GIF-образ. Вы должны добавить специальные проверки, чтобы определить, какой тип содержимого файла и отправить соответствующий заголовок Content-Type
.
Вам нужно указать заголовок Content-Length
:
header("Content-Length: " . filesize($filename));
Кроме того, вы не должны отправлять заголовок Content-Transfer-Encoding
. Оба спецификатора HTTP / 1.0 и HTTP / 1.1 указывают, что «HTTP не использует поле Content-Transfer-Encoding (CTE) RFC 1521».
Я использую следующий метод в phunction, и до сих пор у меня не было никаких проблем:
function Download($path, $speed = null) { if (is_file($path) === true) { $file = @fopen($path, 'rb'); $speed = (isset($speed) === true) ? round($speed * 1024) : 524288; if (is_resource($file) === true) { set_time_limit(0); ignore_user_abort(false); while (ob_get_level() > 0) { ob_end_clean(); } header('Expires: 0'); header('Pragma: public'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Type: application/octet-stream'); header('Content-Length: ' . sprintf('%u', filesize($path))); header('Content-Disposition: attachment; filename="' . basename($path) . '"'); header('Content-Transfer-Encoding: binary'); while (feof($file) !== true) { echo fread($file, $speed); while (ob_get_level() > 0) { ob_end_flush(); } flush(); sleep(1); } fclose($file); } exit(); } return false; }
Вы можете попробовать это просто:
Download('/path/to/file.ext');
Эта проблема так же, как и проект моего веб-сайта. Этот код, который я использовал:
<?php $file = $_SERVER["DOCUMENT_ROOT"].'/.../.../'.$_GET['file']; if(!file) { // File doesn't exist, output error die('file not found'); } else { //$file_extension = strtolower(substr(strrchr($file,"."),1)); $file_extension = end(explode(".", $file)); switch( $fileExtension) { case "pdf": $ctype="application/pdf"; break; case "exe": $ctype="application/octet-stream"; break; case "zip": $ctype="application/zip"; break; case "doc": $ctype="application/msword"; break; case "xls": $ctype="application/vnd.ms-excel"; break; case "ppt": $ctype="application/vnd.ms-powerpoint"; break; case "gif": $ctype="image/gif"; break; case "png": $ctype="image/png"; break; case "jpeg": case "jpg": $ctype="image/jpg"; break; default: $ctype="application/force-download"; } nocache_headers(); // Set headers header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public"); // required for certain browsers header("Content-Description: File Transfer"); header("Content-Type: $ctype"); header("Content-Disposition: attachment; filename=".$file.";" ); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($file)); readfile($file); } ?>
Я думаю, что проблема связана с настройками сервера, такими как настройка PHP или настройка кеша, но я не имею никакой идеи сделать это по моему мнению.
Я делаю это, чтобы загрузить PDF …
$filename = 'Application.pdf'; header("Content-Type: application/pdf"); header("Content-Disposition: attachment; filename=$filename"); echo $pdf;
Я думаю, что вам не хватает последней строки, в которой вы действительно отправляете содержимое файла из того, что у вас есть в $file
.
Pablo
Файл был открыт для меня, когда я сменил каталог на расположение файла.
$reportLocation = REPORTSLOCATION; $curDir = getcwd(); chdir($reportLocation); if (file_exists($filename)) { header('Content-Disposition: attachment; filename="' . $filename . '"'); header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Length: ' . filesize($filename)); header('Content-Transfer-Encoding: binary'); header('Cache-Control: must-revalidate'); header('Pragma: public'); ob_clean(); flush(); readfile($filename); } chdir($curDir);
Трюк заключается в том, чтобы проверить с помощью file_exists, чтобы подтвердить правильный путь. Большая путаница в том, что для путей PHP вам не нужно начинать с '/', чтобы сказать, что ваш путь к началу веб-сайта.
'/folder/file.ext' #bad, needs to know the real full path
в php / уже есть основной путь к веб-сайту, вам не нужно упоминать об этом. Просто:
'folder/file.ext' #relative to the / website
Это будет работать с file_exists, именем файла заголовка, readfile и т. Д. …