2012-02-14 104 views
2

是很常見的,它們位於公共文件夾外的PHP服務器下載的文件:服務下載文件用PHP

$fp = fopen($file,"r") ; 
header("Content-Type: application/msword"); 
header('Content-Disposition: attachment; filename="'.$filename.'"'); 

while (! feof($fp)) { 
    $buff = fread($fp,4096); 
    echo $buff; 
} 

我有兩個問題:

  1. 與服務的靜態文件比較網絡服務器(直接文件URL);該方法是否需要更多資源(內存和CPU),因爲PHP需要讀取文件並交付?

  2. 我們如何在頁面上顯示一些文字?當我們定義header時,我們沒有php腳本的html輸出。

回答

2

1既然你要處理與此腳本它需要更多的資源 不僅僅是正常的下載鏈接的文件。但這取決於您的需求。如果你認爲這些文件需要更多的安全性。假設只有經過身份驗證的用戶才能下載該文件,並且只有該文件屬於他。然後你需要驗證那些。在這種情況下,你需要在你的問題中提供的代碼。如果你的文件對公衆開放,那麼你可以顯示文件的直接鏈接,可能暫時在公共場所找到它們。

2我可以建議你兩種方法來執行此操作。

方法1:

需要Javascript支持,以在方便的方式執行這種要求。假設您需要在可下載的頁面上顯示一些HTML。你可以用你想要的HTML創建一個頁面,你可以放一個下載按鈕。

<input type="button" name="cmdDownload" id="cmdDownload" value="Download" onclick="downloadFile('<?php echo $pathToTheFile; ?>');" />

而且你可以保持隱藏的iframe來處理下載。

<iframe id="downloadFrame" style="display:none"></iframe> 

假設你的PHP下載頁面是download.php。

然後,你可以有這樣的JavaScript功能。

<script type="text/javascript"> 
function downloadFile(filepath) 
{ 
    var ifrme = document.getElementById("downloadFrame"); 
    ifrme.src = "download.php?filepath="+filepath; 
} 
</script> 

方法2:

除了上面的方法,你可以使用META刷新爲好。

<meta http-equiv="Refresh" content="3;URL=<?php echo $fullHTTPathToYourFile ?>" /> 

你也可以用這個HTML顯示。

+0

非常微妙的JS技巧! – Googlebot 2012-02-14 01:50:35

2
  1. 不是直接服務於該文件,因爲你現在涉及PHP
  2. 沒有稍多開銷,你不能。如果你輸出一個(比如說)應用程序/ msword頭文件,那麼你輸出的所有東西都將被視爲.doc文件的一部分,並導致它被破壞。如果你想輸出一些文本,你必須做兩部分下載 - 輸出一個標準的HTML頁面的文本,幷包括定時<meta>(或JavaScript)重定向轉發用戶到實際的下載url。
3
  1. 是,讀取文件用PHP和寫入到一個用戶會根據文件的大小是使用過程中的更多的內存和CPU。
  2. 首先顯示一個頁面,並在頁面上有一個按鈕/鏈接,讓用戶可以看到實際的下載腳本。

另外我會建議使用內容長度標題以及。

header('Content-Length: '. filesize($path)); 
+0

非常感謝關於'header'的信息。它拯救了我的日子 – 2015-06-19 06:49:26

1

如果輸出緩衝處於活動狀態,使用PHP提供文件將消耗大量內存,並且性能會比apache提供的常規文件更糟糕。

所以要添加的東西已經給出了答案:

  • 完成時使用ob_end_flush()發送頭,結束輸出緩衝,因此該文件內容將不會在內存中開始輸出
  • 之前被緩存
  • readfile()可能流從磁盤上的文件到網絡更有效地比你的循環

有人說,但可以強調也不過分:包括Content-Length標題,因爲它將允許下載程序測量進度。