2011-06-13 43 views
4

我有一個使用PDF和純文本產生良好結果的強制下載腳本,並且使用ZIP歸檔(它們在Windows中工作,而不是在Linux中)是半正常的。但是,應用程序文件和圖像都失敗。這些構成了我必須處理的絕大多數文件。如我在這裏看到的類似主題中所建議的那樣,壓縮所有下載並不是一種選擇。我該如何解決這個PHP下載腳本,它正在破壞文件?

失敗的文件下載到它們的完整大小,並以正確的名稱寫入磁盤。嘗試打開它們會導致錯誤消息,這在類型之間會有所不同。在hexdump都下載文件到他們的原件進行比較,我可以看到,腳本在每個下載的文件的開頭插入以下字符:

ef bb bf 

下載的文件,則再現了原作,直到它停止在其指定的大小 - 原來的最後6個字符總是缺失。

不幸的是,我不知道二進制文件是如何構成的,這些字符可能意味着什麼,或者腳本如何/爲什麼插入它們。

這是腳本-是:

$file = '94.ppt'; 
$path = $_SERVER['DOCUMENT_ROOT']."/relative/path/"; 
$full_path = $path.$file; 
if ($fd = fopen ($full_path, "r")) { 
    $fsize = filesize($full_path); 
    $path_parts = pathinfo($full_path); 
    $ext = strtolower($path_parts["extension"]); 
    switch ($ext) { 
     case "pdf": 
      header("Content-type: application/pdf"); 
      header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 
     break; 
     case "txt": 
      header("Content-type: text/plain"); 
      header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 
     break; 
     case "jpg": 
      header("Content-type: image/jpeg"); 
      header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 
     break; 
     case "ppt": 
      header("Content-Type: application/vnd.ms-powerpoint"); 
      header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 
     break; 
     default; 
      header("Content-type: application/octet-stream"); 
      header("Content-Disposition: filename=\"".$path_parts["basename"]."\""); 
    } 
    header("Content-Transfer-Encoding: binary"); 
    header("Content-length: $fsize"); 
    header("Cache-control: private"); 
    while(!feof($fd)) { 
     $buffer = fread($fd, 2048); 
     echo $buffer; 
    } 
} 
fclose ($fd); 
exit; 

開發系統是PHP 5.3.2-1在Apache 2.2.14(Ubuntu的)。生產主機在Apache 2.0.63(某種類型的Linux)上是PHP 5.2.9。

+0

不確定它是否是您的文章中的錯字或實際代碼「default」應該是:不是; – bumperbox 2011-06-13 09:47:06

回答

1

EF BB BF是UTF-8編碼Byte Order Mark(BOM)。我懷疑有一些配置選項可以關閉BOM。

編輯:文件編輯器應允許您在以相關字符編碼(例如UTF-8)保存文件時關閉BOM。

+0

因爲腳本(或其包含的某個腳本)被保存爲UTF-8,並且編輯器預先添加了一個現在正在傳遞給輸出的BOM,所以我不會感到驚訝。配置設置不會解決該問題 – cHao 2011-06-13 09:46:13

+0

編輯器中的配置設置會:-)另外,OP提到圖像失敗,因此它不能作爲BOM前綴源文件。 – andyb 2011-06-13 09:46:49

+0

Touche。 :)我正在考慮PHP設置,而不是編輯器設置。 – cHao 2011-06-13 09:48:05

3

EF BB BF是標準的UTF-8 byte order mark。有些人擁有reported,當腳本中包含的一些PHP文件是UTF-8編碼時,會發生這種情況;一些版本的PHP通過發送UTF-8字節順序標記來對此作出反應。上面的鏈接建議在開始推出文件的內容之前,在腳本的開頭調用ob_start(),然後再調用ob_end_clean() - 這樣字節順序標記就會被捕獲到輸出緩衝區中。

此外,您可以簡單地使用fpassthru將文件傳輸到輸出,而不是在循環中讀寫。

+0

非常感謝:目前我處於壓力之下,無法獲得任何東西 - 任何工作。但是我打算在夏季的晚些時候再次審視這個項目。 – hnmcc 2011-06-13 10:31:06

3

您的PHP腳本文件似乎在UTF-8 with BOM中編碼,該文件在開頭的<?php定界符之前的文件開始處是正確的。這些字節在您的實際輸出之前發送,因此會破壞您的數據。

您只需將其刪除並將編輯器配置爲不使用UTF-8的BOM。

+0

謝謝你們,劇本現在完美無缺。原因是Notepad ++中的編碼設置。這本來就需要我一個時代 - 如果有的話 - 自己去找。 – hnmcc 2011-06-13 10:31:39

+0

@hnmcc:這是一個常見問題,尤其是因爲UTF-8不需要BOM,因爲只有一個字節順序 - 除了自動編碼檢測外。 – Gumbo 2011-06-13 10:36:07

+0

我有一個圖像文件注入了某種腐敗,也許它是bom。但是,我從來沒有編輯過這個文件。沒有注入東西的文件通過網絡應用程序上傳並通過FTP下載,之前或之後沒有奇怪的代碼。但是,通過一個網絡應用程序下載時出現的怪異代碼,使文件損壞,出現在網絡上的應用程序隱藏的文件。該文件正在被fread讀取,每次循環1024字節,發送到每個循環的緩衝區。不知怎的,腐敗發生在那裏,但只有當我編輯了包含循環的php文件時。 – DanAllen 2015-08-13 18:33:41

相關問題