簡體   English   中英

PHP readfile() 導致文件下載損壞

[英]PHP readfile() causing corrupt file downloads

我正在使用 php 腳本在必要的 javascript 計時器之后從我的網站提供下載,此 php 腳本包含在導致下載的內容中。 但是無論我嘗試什么,下載的文件都已損壞。 誰能幫我指出我哪里出錯了。

這是我的代碼

     <?php
include "db.php";    
 $id = htmlspecialchars($_GET['id']);
 $error = false;
    $conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
    if(!($conn)) echo "Failed To Connect To The Database!";
    else{   
        if(mysql_select_db(DB_NAME,$conn)){
            $qry = "SELECT Link FROM downloads WHERE ID=$id";
            try{
                $result = mysql_query($qry);
                if(mysql_num_rows($result)==1){
                    while($rows = mysql_fetch_array($result)){
                        $f=$rows['Link'];
                    }
                    //pathinfo returns an array of information
                    $path = pathinfo($f);
                    //basename say the filename+extension
                    $n = $path['basename'];
                    //NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
                    header('Content-type: application/octet-stream');
                    header('Content-Length: ' . filesize($f));
                    //This would be the one to rename the file
                    header('Content-Disposition: attachment; filename='.$n.'');
                    //Finally it reads the file and prepare the output
                    readfile($f);
                    exit();
                }else $error = true;
            }catch(Exception $e){
                $error = true;
            }
            if($error) 
            {
                header("Status: 404 Not Found");
                }
        }
  }
?> 

這有助於我在打開更多輸出緩沖區的情況下。

//NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($f));
//This would be the one to rename the file
header('Content-Disposition: attachment; filename='.$n.'');
//clean all levels of output buffering
while (ob_get_level()) {
    ob_end_clean();
}
readfile($f);
exit();

首先,正如一些人在評論中指出的那樣,刪除第一行開始 PHP 標記( <?php )之前的所有空格,這應該可以解決問題(除非其他文件包含或需要該文件)。

當您在屏幕上打印任何內容時,即使是單個空格,您的服務器都會發送標題以及要打印的內容(在這種情況下,您的空格)。 為了防止這種情況發生,您可以:

a) 在寫完標題之前不要打印任何東西;

b) 運行 ob_start() 作為腳本中的第一件事,編寫內容,編輯標題,然后在您希望將內容發送到用戶瀏覽器時運行 ob_flush() 和 ob_clean()。

在 b) 中,即使您成功寫入標頭而沒有出錯,空格也會損壞您的二進制文件 您應該只編寫二進制內容,而不是包含二進制內容的幾個空格。

ob_前綴代表輸出緩沖區。 調用ob_start() ,您告訴應用程序您輸出的所有內容( echoprintf等)都應保存在內存中,直到您明確告訴它“轉到”( ob_flush() )到客戶端ob_flush() 這樣,您將輸出與標題一起保存,當您完成編寫它們時,它們將與內容一起發送。

           ob_start();//add this to the beginning of your code 

      if (file_exists($filepath) && is_readable($filepath) ) {
header('Content-Description: File Transfer');
 header("Content-Type: application/octet-stream");
 header("Content-Disposition: attachment; filename=$files");
 header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
   header('Pragma: public');
 header("content-length=".filesize($filepath));
 header("Content-Transfer-Encoding: binary");

   /*add while (ob_get_level()) {
       ob_end_clean();
         }  before readfile()*/
  while (ob_get_level()) {
ob_end_clean();
   }
    flush();
   readfile($filepath);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM