首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 文件下載亂碼損壞問題的根因分析與解決方案

     編輯:PHP 綜合知識

在 PHP 開發中實作檔案下載功能時,常遇到下載後的圖片無法開啟、文字檔出現亂碼、檔案大小異常增加等問題。這通常是因為輸出緩衝區殘留內容,導致檔案資料被額外字元污染。

問題現象

使用 readfile() 輸出檔案時,下載的圖片用編輯器開啟提示「檔案損壞」,但縮圖仍可顯示;文字檔頭尾多出不明字元;檔案大小比原始檔大約 1KB。經排查,確認為輸出前已有內容輸出(如空白字元、BOM、錯誤訊息等),導致 HTTP 回應標頭與檔案二進位資料混雜。

核心解決方法

在輸出檔案前,必須清空輸出緩衝區並關閉緩衝,確保只輸出純檔案內容:

public function download() {
    $upload = M('upload');
    $data = $upload->find($_GET['id']);
    
    if (empty($data)) {
        header('HTTP/1.0 404 Not Found');
        header('Location: .');
    } else {
        $path = './public/Uploads/' . $data['savename'];
        
        // 設定正確的標頭
        header("Content-Type: " . $data['type']);
        header('Content-Disposition: attachment; filename="' . $data['name'] . '"');
        header('Content-Length: ' . $data['size']);
        
        // 關鍵步驟:清空緩衝區並關閉輸出緩衝
        ob_clean();
        flush();
        
        // 輸出檔案
        readfile($path);
    }
}

關鍵點解析

  • ob_clean():丟棄輸出緩衝區中的內容,防止先前的空白、錯誤訊息混入檔案。
  • flush():將已發送的標頭立即推送給瀏覽器,確保標頭與檔案資料分離。
  • Content-Length:必須精確指定檔案大小,否則瀏覽器可能無法正確判斷下載完成時間。
  • 避免在 readfile() 前有任何 echo、print、HTML 空白或 BOM。

進階建議

若專案使用框架(如 ThinkPHP、Laravel),建議使用框架內建的檔案下載回應類別(如 Response::download()),可自動處理緩衝、標頭、大檔案分塊傳輸等細節,更安全可靠。

掌握輸出緩衝控制,是解決 PHP 檔案下載損壞的關鍵。記得在輸出二進位檔案前,永遠先 ob_clean() 與 flush()。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved