2010-08-31 94 views
2

如果我轉到http://site.com/uploads/file.pdf我可以檢索一個文件。通過php向用戶提供文件通過php

但是,如果我有一個腳本,例如:

<?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" 
+0

當你沒有從代碼中檢索到「Content-Type」,「Content-Disposition」和「Content-Length」時,你會得到同樣的錯誤,而是將其手動設置爲該特定文件? – Robert 2010-08-31 15:59:46

回答

1

首先,我首先檢查HTTP標題。您可以使用「Live HTTP標頭」擴展輕鬆地在Firefox中執行此操作;不確定其他瀏覽器中的等價物。這將讓你驗證頭是否真的被設置爲「application/pdf」,以及你的其他頭文件是否已經設置好。

如果沒有設置標頭,則可能會在調用header()之前無意中發送輸出。 <?php標籤之前是否有空格?

+0

上面更新了整個文件的頭文件代碼。 – Chris 2010-08-31 16:02:42

+0

雖然這不是一個標題問題,我意識到我有一個錯字... readfile($文件)應該是readfile($ fileName),但直播的http頭有幫助。謝謝並遺憾浪費時間。 – Chris 2010-08-31 16:12:37

0

您確定application/pdf是您的瀏覽器實際看到的標題嗎?

您可以使用各種HTTP開發工具檢查,例如Mac或Firebug for Firefox的HTTP Client

0

我用這個,它的工作原理。

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); 
} 
+0

我已經嘗試過應用程序/八位字節流,並導致相同的問題。 – Chris 2010-08-31 16:04:51

+0

您是否嘗試在我的示例的相同順序中發送標題? – 2010-08-31 16:20:15

0

嘗試預先設置「error_reporting(0);」。我在http://php.net/readfile的評論中找到了這個(你從這個例子中得到了這個例子)。

另一件可能成爲問題的事情是您的文件大小。過去有關於PHP5的問題(我們在這裏討論2005,所以我希望現在已經解決了)閱讀文件> 2MB有困難。如果您的文件大小超過此值,您可能需要驗證它是否讀取整個文件。

+0

文件應該小於500KB,所以大小不應該是一個問題。 – Chris 2010-08-31 16:05:51