代码之家  ›  专栏  ›  技术社区  ›  Chris

通过php通过http向用户提供文件

  •  2
  • Chris  · 技术社区  · 14 年前

    http://site.com/uploads/file.pdf 我可以检索一个文件。

    <?php 
    
    ini_set('display_errors',1);
    error_reporting(E_ALL|E_STRICT);
    
    //require global definitions 
    require_once("includes/globals.php"); 
    //validate the user before continuing 
    isValidUser(); 
    $subTitle = "Attachment";   
    $attachmentPath = "/var/www/html/DEVELOPMENT/serviceNow/selfService/uploads/";
    if(isset($_GET['id']) and !empty($_GET['id'])){
        //first lookup attachment meta information 
        $a = new Attachment(); 
        $attachment = $a->get($_GET['id']); 
        //filename will be original file name with user name.n prepended 
        $fileName = $attachmentPath.$_SESSION['nameN'].'-'.$attachment->file_name; 
        //instantiate new attachmentDownload and query for attachment chunks 
        $a = new AttachmentDownload(); 
        $chunks= $a->getRecords(array('sys_attachment'=>$_GET['id'], '__order_by'=>'position')); 
    
    
        $fh = fopen($fileName.'.gz','w');                                                      
        // read and base64 encode file contents 
        foreach($chunks as $chunk){
                fwrite($fh, base64_decode($chunk->data));   
        }
        fclose($fh);
    
        //open up filename for writing 
        $fh = fopen($fileName,'w');     
        //open up filename.gz for extraction                                
        $zd = gzopen($fileName.'.gz', "r");
        //iterate over file and write contents 
        while (!feof($zd)) {
                fwrite($fh, gzread($zd, 60*57));    
        }
        fclose($fh); 
        gzclose($zd);
        unlink($fileName.'.gz'); 
        $info = pathinfo($fileName); 
    
        header('Content-Description: File Transfer');
        header('Content-Type: '.Mimetypes::get($info['extension']));
        header('Content-Disposition: attachment; filename=' . basename($fileName));
        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($fileName));
        ob_clean();
        flush();
        readfile($fileName);
        exit();
    }else{
        header("location: ".$links['status']."?".urlencode("item=incident&action=view&status=-1&place=".$links['home']));   
    }
    
    
    ?>
    

    "File type plain text document (text/plain) is not supported"
    
    4 回复  |  直到 14 年前
        1
  •  1
  •   ngroot    14 年前

    首先,我先检查HTTP头。您可以在Firefox中使用“livehttpheaders”扩展轻松地实现这一点;不确定在其他浏览器中是否有等价物。这将允许您验证标头是否实际设置为“application/pdf”,以及其他标头是否也设置为“application/pdf”。

    如果没有设置任何标头,则可能会在调用之前无意中发送输出 header() <?php 标签?

        2
  •  0
  •   ianmclaury    14 年前

    您确定application/pdf是浏览器实际看到的标题吗?

    HTTP Client 适用于Mac或Firefox的Firebug。

        3
  •  0
  •   Marco Demaio    14 年前

    if(file_exists($file_serverfullpath))
    {    
       header("Pragma: public");
       header("Expires: 0");
       header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
       header("Cache-Control: private", false);
    
       //sending download file
       header("Content-Type: application/octet-stream"); //application/octet-stream is more generic it works because in now days browsers are able to detect file anyway
       header("Content-Disposition: attachment; filename=\"" . basename($file_serverfullpath) . "\""); //ok
       header("Content-Transfer-Encoding: binary");
       header("Content-Length: " . filesize($file_serverfullpath)); //ok
       readfile($file_serverfullpath);
    }
    
        4
  •  0
  •   schuilr    14 年前

    请尝试在“error_reporting(0);”前面加上前缀。我在网站的评论中发现了这个 http://php.net/readfile (您从中获取此示例)。

    另一个问题是文件大小。过去曾报道过PHP5(我们在这里讨论的是2005年,所以我希望现在可以解决这个问题)在读取大于2MB的文件时遇到问题。如果文件大小超过此值,您可能需要验证它是否读取整个文件。