下面是我的下载网关的部分代码
if (!isset($_GET['f']) || empty($_GET['f'])) {die("<h1>URL Malfunction</h1><br/><p><i>Please Try Later</i>");}
if (strpos($_GET['f'], "'0") !== FALSE){ die("<h1>URL Malfunction</h1><br/><p><i>Please Try Later</i>");}
#Check URL, find resource Path
$fileName = basename($_GET['f']);
$file_path=(string)makeDownloadFilePath($fileName,"dir");
if(!is_file($file_path)){die("<h1>404 Not found</h1><br/><p><i>The resource you requested is not available</i>");}
$fileSize = filesize($file_path);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public"); #Build Response#
header("Content-Description: File Transfer");
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename='"$fileName'"");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . $fileSize);
$file = @fopen($file_path,"rb");
if ($file) {
while(!feof($file)) { #File Transfer#
print(fread($file, 1024*8));
flush();
if (connection_status()!=0) {
@fclose($file);
die();
}
}
@fclose($file);
//The File is Downloaded . Closing Connections
我使用GET方法来接收文件名。文件名及其路径将从gateway生成。现在的问题是,当我点击下载页面,而不是显示下载对话框,浏览器只是呈现文件内容作为屏幕上的文本。例如,我正在下载foo.mp3。二进制内容在屏幕上显示为奇怪的文本。它会发出这样的警告:我们不能更改header。
谁能告诉我哪里出错了?谢谢
我们不能更改header。
当你在php头命令之前打印任何东西时,会出现这个错误。
导致此错误的最常见原因是在文件(或其包含的一个)的开始<?php
标记之前有一些前导空白。
<
应该是文件中的第一个字符,在它被直接写入输出缓冲区之前的任何字符都可能导致发送报头。当以这种方式强制下载文件时,也会导致文件损坏。
使用readfile代替fopen,并使用ob_clean(), ob_flush():
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$Name.'"');
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($musicPath));
ob_clean();
flush();
readfile($musicPath);
ob_flush();
是否使用输出缓冲区?
尝试在发送头信息之前添加ob_start();
,这可能会解决您的问题。
你可以在这里找到更多的信息
谢谢大家的帮助。问题是我使用了
error_reporting(E_ALL);
ini_set('display_errors', true);
flush();
用于调试我的一个包含。
我只是把它去掉了。