使用PHP下载文件会出错

时间:2016-10-13 10:52:04

标签: php

注意:我已尝试实施以下提供的解决方案:How to fix "Headers already sent" error in PHP但它没有帮助,所以我发布了这个问题。 我已经就类似问题发表了各种帖子,但没有一个解决方案有效。以下是我的代码:

<form role="form" method="POST">
 <input type="submit" name="dff" id="dff" class="btn btn-default" value="Download Franchisee Form"></input>
</form>
<?php
 if(isset($_POST['dff']))
 {
  $yourfile="MyFile.pdf";
  $fp = @fopen($yourfile, 'rb');
  if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
  {
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header("Content-Transfer-Encoding: binary");
    header('Pragma: public');
    header("Content-Length: ".filesize($yourfile));
  }
  else
  {
    header('Content-Type: "application/octet-stream"');
    header('Content-Disposition: attachment; filename="yourname.file"');
    header("Content-Transfer-Encoding: binary");
    header('Expires: 0');
    header('Pragma: no-cache');
    header("Content-Length: ".filesize($yourfile));
  }
  fpassthru($fp);
  fclose($fp);
 }
?>

点击此按钮后出现以下错误:

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 133

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 134

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 135

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 136

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 137

Warning: Cannot modify header information - headers already sent by (output started at C:\xampp\htdocs\GoogleKids\Franchisee.php:116) in C:\xampp\htdocs\GoogleKids\Franchisee.php on line 138

之后,我在网页上看到如下所示的不可读符号:

%PDF-1.5 %���� 1 0 obj <> endobj 2 0 obj <> endobj 3 0 obj <>/ExtGState<>/Font<>/ProcSet[/PDF/Text/ImageB/ImageC/ImageI] >>/MediaBox[ 0 0 595.32 841.92] /Contents 7 0 R/Group<>/Tabs/S>> endobj 4 0 obj <> stream ����JFIF``��ZExifMM*JQQ�Q�������C    !(!0*21/*.-4;K@48G9-.BYBGNPTUT3?]c\RbKSTQ��C''Q6.6QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ��d9"�� ���}!1AQa"q2���#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������� ���w!1AQaq"2�B���� #3R�br� $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz����

注意: 即使我分别在脚本的开头和结尾使用了ob_start()和ob_flush(),我仍然遇到了同样的错误。

注意:我没有在完整页面上使用任何其他PHP脚本。这是唯一的脚本。但是,我确实有另一个表单标记链接到执行操作的另一个网页,它有自己独立的提交按钮,具有唯一的名称和ID。 请帮忙。

2 个答案:

答案 0 :(得分:1)

尝试以下解决方案: 在您的网页上,删除表单标记并使用锚点,如下所示:

<a href="downloads.php?download_file=MyFile.pdf">Download The File</a>

然后,创建一个名为downloads.php的新文件并编写以下代码:

<?php
ignore_user_abort(true);
set_time_limit(0); // disable the time limit for this script

$dl_file = preg_replace("([^\w\s\d\-_~,;:\[\]\(\).]|[\.]{2,})", '', $_GET['download_file']); // simple file name validation
$dl_file = filter_var($dl_file, FILTER_SANITIZE_URL); // Remove (more) invalid characters
$fullPath = $dl_file;

if ($fd = fopen ($fullPath, "r")) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
        header("Content-type: application/pdf");
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a file download
        break;
        // add more headers for other content types here
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
        break;
    }
    header("Content-length: $fsize");
    header("Cache-control: private"); //use this to open files directly
    while(!feof($fd)) {
        $buffer = fread($fd, 2048);
        echo $buffer;
    }
}
fclose ($fd);
exit;
?>

我测试了这段代码,它在Chrome和IE中都非常适合我。确保根据您的要求更改文件名和文件路径。 如果这有助于你,请不要忘记投票。

答案 1 :(得分:0)

你有......

<html><?php
    header('...');
?>

你想......

<?php
    header('...');
?><html>

在PHP标头(...)调用之前可能出现的唯一代码是PHP(或任何服务器端代码),而不是HTML,CSS或纯文本。对于服务器发送任何内容,它必须发送标题,一旦发送,它们就不能重新发送。因此,您必须在发送内容之前设置标题。