在PHP中设置标头时出错

时间:2011-10-27 10:22:28

标签: php http-headers download

下面是我的下载网关中代码的一部分

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方法接收文件名。文件名及其路径将从网关生成。现在问题是当我点击页面中的下载而不是显示下载对话框时,浏览器只是将文件内容呈现为屏幕上的文本。例如,我正在下载foo.mp3。二进制内容在屏幕上显示为奇怪的文本。 它回应了一个警告:我们无法改变标题。标题已发送给...

任何人都可以告诉我,哪里犯了错误?

由于

5 个答案:

答案 0 :(得分:1)

我们无法更改标题。标题已发送到..

当您在php header header命令之前打印任何内容时会出现此错误。

答案 1 :(得分:1)

长期以来,这种错误的最常见原因是您在文件中打开<?php标记之前有一些前导空格(或其中一个包含)。

<应该是文件中的第一个字符,在它被直接写入输出缓冲区之前的任何内容都可能导致标题被发送。以这种方式强制下载文件时,也会导致文件损坏。

答案 2 :(得分:0)

使用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();

答案 3 :(得分:0)

您使用的是输出缓冲区吗?

在发送标题信息之前尝试添加ob_start();,这可能会解决您的问题。

您可以找到有关它的更多信息here

答案 4 :(得分:0)

谢谢大家的帮助。问题是我正在使用

error_reporting(E_ALL);
ini_set('display_errors', true);
flush();

用于我的一个包含中的调试。

我刚删除它。现在它可以工作。