强制下载时无法打开,下载或损坏该文件

时间:2015-09-25 11:26:50

标签: php

这就是我的虚拟主机方案的样子:

enter image description here

这是我遇到问题的代码,试图强制下载文件:

$_SERVER

下载对话框实际上会弹出,但是我的浏览器收到一条错误消息,说它无法读取,因此无法打开或下载。

我尝试将$fetch_file = $set_query->fetch_assoc(); $file = "../library/".$fetch_file["file_name"]; if (file_exists($file) && is_file($file)) { if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); } header('Content-Length: ' . filesize($file)); header('Pragma: public'); header('Expires: 0'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=\"'.basename($file).'\"'); header('Content-Transfer-Encoding: binary'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Connection: close'); ob_end_flush(); ob_end_clean(); readfile($file); exit; ob_end_flush()放在标题之前,但它没有用完。我不知道为什么下载对话框会正确显示要下载的文件但是说它无法读取也无法打开。

我设法通过使用:

来解决这个问题
ob_end_clean()

该对话框现在打开并下载文件,但它不会在本地打开,说它已损坏。当我以文本形式打开它时,它包含我页面的HTML。

我的下载页面是通过// digital_lub/JKAJSD831.pdf $file = UPLOAD_PATH.$fetch_file["file_name"]; 网址重写包含在index.php中的。这是.htaccess

index.php

3 个答案:

答案 0 :(得分:1)

基本上,您的问题是您发送的数据不仅仅是文件。由于您的页面实际上包含在另一个页面中,该页面在到达任何类型的下载逻辑之前显示一些标题,因此额外的HTML将成为您下载文件的一部分,从而破坏它。

有两个步骤可以避免这种情况:

  1. 删除ob_end_flush(),因为它仍会将缓冲区刷新到客户端,而您显然不想要它,只留下ob_end_clean(),这会破坏其中的任何内容缓冲液中。

  2. 在包含子页面(例如下载页面)的最顶层文档index.php中,将ob_start()放在最开头,以捕获绝对所有输出并添加{{3}在最后输出你的内容。

  3. 这将创建2个执行路径:

    • 保存输出,生成页面,刷新输出,从而显示页面。
    • 保存输出,触发下载,销毁输出,发送文件数据,提前退出。

    这可确保只将您的文件数据发送到客户端。

    这是这个逻辑的一个基本例子:

    • index.php

      <?php
      ob_start();
      echo '__HEADER__';
      require('page.php');
      echo '__FOOTER__';
      ob_end_flush();
      ?>
      
    • page.php

      <?php
      ob_end_clean();
      readfile('test.txt');
      exit();
      ?>
      
    • test.txt

      __TEST__
      

    这应该只输出__TEST__

答案 1 :(得分:0)

我试过了你并没有关闭你的if支架;),我确定这不是原因,你在这里错过了但是当我尝试它时,我能够下载文件。
文件是png,您可以手动尝试使用php脚本的文件,如果不是,那么它可能是您的服务器权限问题。

答案 2 :(得分:0)

您必须指定文件扩展名/类型,浏览器不会猜到它:) 这里有一个 PHP 脚本,如果您的服务器可以处理更多类型的文件,您可以自定义该脚本。

<?php
    //---------------------------------------------------------
    //----------------- MIME TYPE DEFINITION ------------------
    //---------------------------------------------------------
    $mimeType = array() ;

    #[text]
    $mimeType["txt"]    = "text/plain" ;
    $mimeType["sql"]    = "text/plain" ;
    $mimeType["htm"]    = "text/html" ;
    $mimeType["html"]   = "text/html" ;
    $mimeType["css"]    = "text/css" ;

    #[image]
    $mimeType["png"]    = "image/png" ;
    $mimeType["gif"]    = "image/gif" ;
    $mimeType["jpg"]    = "image/jpeg" ;
    $mimeType["jpeg"]   = "image/jpeg" ;
    $mimeType["bmp"]    = "image/bmp" ;
    $mimeType["tif"]    = "image/tiff" ;

    #[archives]
    $mimeType["bz2"]    = "application/x-bzip" ;
    $mimeType["gz"]     = "application/x-gzip" ;
    $mimeType["tar"]    = "application/x-tar";
    $mimeType["zip"]    = "application/zip";

    #[audio]
    $mimeType["aif"]    = "audio/aiff";
    $mimeType["aiff"]   = "audio/aiff";
    $mimeType["mid"]    = "audio/mid" ;
    $mimeType["midi"]   = "audio/mid";
    $mimeType["mp3"]    = "audio/mpeg" ;
    $mimeType["ogg"]    = "audio/ogg" ;
    $mimeType["wav"]    = "audio/wav" ;
    $mimeType["wma"]    = "audio/x-ms-wma" ;

    #[video]
    $mimeType["asf"]    = "video/x-ms-asf" ;
    $mimeType["asx"]    = "video/x-ms-asf" ;
    $mimeType["avi"]    = "video/avi" ;
    $mimeType["mpg"]    = "video/mpeg" ;
    $mimeType["mpeg"]   = "video/mpeg" ;
    $mimeType["wmv"]    = "video/x-ms-wmv" ;
    $mimeType["wmx"]    = "video/x-ms-wmx" ;

    #[xml]
    $mimeType["xml"]    = "text/xml" ;
    $mimeType["xsl"]    = "text/xsl" ;

    #[microsoft]
    $mimeType["doc"]    = "application/msword" ;
    $mimeType["docx"]   = "application/msword" ;
    $mimeType["rtf"]    = "application/msword" ;
    $mimeType["xls"]    = "application/excel" ;
    $mimeType["xlsm"]   = "application/excel" ;
    $mimeType["xlt"]    = "application/excel" ;
    $mimeType["xlsx"]   = "application/excel" ;
    $mimeType["pps"]    = "application/vnd.ms-powerpoint" ;
    $mimeType["ppt"]    = "application/vnd.ms-powerpoint" ;

    #[adobe]
    $mimeType["pdf"]    = "application/pdf" ;
    $mimeType["ai"]     = "application/postscript" ;
    $mimeType["eps"]    = "application/postscript" ;
    $mimeType["psd"]    = "image/psd" ;

    #[macromedia]
    $mimeType["swf"]    = "application/x-shockwave-flash" ;

    #[real]
    $mimeType["ra"]     = "audio/vnd.rn-realaudio" ;
    $mimeType["ram"]    = "audio/x-pn-realaudio" ;
    $mimeType["rm"]     = "application/vnd.rn-realmedia" ;
    $mimeType["rv"]     = "video/vnd.rn-realvideo" ;

    #[other]
    $mimeType["exe"]    = "application/x-msdownload" ;
    $mimeType["pls"]    = "audio/scpls" ;
    $mimeType["m3u"]    = "audio/x-mpegurl" ;
    // <--

    //---------------------------------------------------------
    //----------- INITIALIZING DOWNLOAD PROCESS ---------------
    //---------------------------------------------------------
    $fileToUpload; // TODO! $_REQUEST['PATH/TO/FILE/FILENAME.FILEEXTENSION'] ??
    if (strlen(trim($file_to_upload_s)) == 0) {
        print '[ERROR] file name is empty' ;
        return ;
    }
    $fileExtension = pathinfo($fileToUpload, PATHINFO_EXTENSION );
    $fileExtension = strtolower($fileExtension);
    if (strlen(trim($fileExtension)) == 0) {
        print '[ERROR] file extension is not mentioned' ;
        return ;
    }

    if(array_key_exists($fileExtension, $mimeType ) === FALSE ) {
        print '[ERROR] server does not support this file extension [' . $fileExtension . '], configuration is missing' ;
        return;
    } 

    //---------------------------------------------------------
    //------------- STARTING DOWNLOAD PROCESS -----------------
    //---------------------------------------------------------
    header('Content-Type: ' . $mimeType[$fileExtension]);
    header('Content-Disposition: attachment; filename="' . $fileToUpload . '"');
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: ' . filesize($fileToUpload));
    header('Accept-Ranges: bytes');
    header('Cache-Control: private');
    header('Pragma: private');
    header('Expires: Mon, 1 Jan 1970 00:00:00 GMT');
    readfile($fileToUpload);
?>