2012-04-13 265 views
4

我有一個很奇怪的問題,我的下載腳本爲什麼我下載的文件一直損壞或損壞?

它基本上

1.gets文件ID以「GET」方法

2.gets從該文件的名稱和位置數據庫

它3.sends與報頭中的客戶端和READFILE

但ST RANGELY該文件永遠是爲破壞或損壞

一樣,如果它是一個zip或rar文件 文件大小是正確的,它打開OK

,但我不能打開它內部的壓縮文件,這時候我得到的文件損壞錯誤

這是怪異的Cuz如果代碼有一個問題,我不應該甚至能夠打開壓縮文件(或至少我覺得我應該不會)

另一件事是我在發送標題之前打印出文件的路徑,以確保一切正常

我已經把文件地址的網址並下載文件,文件是確定沒有錯誤

所以一切發送頭

這裏是我的代碼之前是好的

 $file_id = isset($_GET['id']) && (int)$_GET['id'] != 0 ? (int)$_GET['id'] : exit; 


     //////// finging file info 
     $file = comon::get_all_by_condition('files' , 'id' , $file_id); 
     if(!$file) exit; 
     foreach($file as $file){ 
     $location = $file['location']; 
     $filename = $file['file_name']; 
     } 
     ///////////// 


     $site = comon::get_site_domian(); 

     $ext = trim(end(explode('.' , $filename))); 
     $abslout_path = 'http://'.$site.'/'.$location.'/'.$filename; 
     $relative = $location.'/'.$filename; 



    ////////////////// content type 
      switch($ext) { 
      case 'txt': 
       $cType = 'text/plain'; 
      break;    
      case 'pdf': 
       $cType = 'application/pdf'; 
      break; 

      case 'zip': 
       $cType = 'application/zip'; 
      break; 

      case 'doc': 
       $cType = 'application/msword'; 
      break; 

      case 'xls': 
       $cType = 'application/vnd.ms-excel'; 
      break; 

      case 'ppt': 
       $cType = 'application/vnd.ms-powerpoint'; 
      break; 
      case 'gif': 
       $cType = 'image/gif'; 
      break; 
      case 'png': 
       $cType = 'image/png'; 
      break; 
      case 'jpeg': 
      case 'jpg': 
       $cType = 'image/jpg'; 
      break; 

      default: 
       $cType = 'application/force-download'; 
      break; 
     } 
    //////////////// just checking 

    if(!file_exists($relative)){ 
     echo $relative; 
     echo '<br />'; 
     exit; 
     } 

    if(!is_readable($relative)) 
    exit('its not redable'); 



    if(headers_sent()) 
    exit('headers ? already sent !! '); 



    header('Pragma: public'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Cache-Control: private', false); // required for certain browsers 
    header('Content-Description:File Transfer'); 
    header($_SERVER['SERVER_PROTOCOL'].' 200 OK'); 
    header('Content-Type:'.$cType); 
    header('Content-Disposition: attachment; filename="'. basename($filename) . '";'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Content-Length: ' . filesize($relative)); 
    readfile($abslout_path); 
    exit; 

我已經檢查了標題幾次,他們都很好(我認爲),我也添加了所有人知道的標題只是爲了確保!

我開始覺得它可能不是腳本 ,比如char編碼或文件夾權限!或類似的東西 !!

我錯過了什麼?

回答

7

這似乎只是強制下載代碼的分配,這裏是一個很好的函數,我使用所有的時間。它也會處理超過2GB的文件。

<?php 
$file_id = (isset($_GET['id']) && (int)$_GET['id'] != 0) ? (int)$_GET['id'] : exit; 

/*finding file info*/ 
$file = comon::get_all_by_condition('files', 'id', $file_id); 
$path = $file['location'] . '/' . $file['file_name']; 

if (!is_file($path)) { 
    echo 'File not found.('.$path.')'; 
} elseif (is_dir($path)) { 
    echo 'Cannot download folder.'; 
} else { 
    send_download($path); 
} 

return; 

//The function with example headers 
function send_download($file) { 
    $basename = basename($file); 
    $length = sprintf("%u", filesize($file)); 

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename="' . $basename . '"'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Connection: Keep-Alive'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: ' . $length); 

    set_time_limit(0); 
    readfile($file); 
} 
?> 
+0

後視圖thanx偉大的工作 – max 2012-04-13 17:51:35

+0

@DanBray多麼可怕的編輯,批評社區的恥辱 – 2016-03-10 18:19:26

+0

@LawrenceCherone使代碼工作如此糟糕?代碼有一個'''缺少''。你認爲把代碼與錯別字放在一起會更好嗎?缺少的'''可能會混淆人並浪費大量時間。 – 2016-03-10 18:22:48

2

您可以使用腳本包含通知或警告,請嘗試禁用你的腳本的頂部報告錯誤:

error_reporting(0); 
2

非常好,樂於助人也...

,但有一個問題你的代碼 -

header('Content-Disposition: attachment; 
filename="'.basename($file).'"'; 

請與本以下更改 -

header('Content-Disposition: attachment; 
filename="'.basename($file).'"'); 

你忘了關閉它。

2
if (file_exists($file)) { 
set_time_limit(0); 
     header('Connection: Keep-Alive'); 
    header('Content-Description: File Transfer'); 
      header('Content-Type: application/octet-stream'); 
      header('Content-Disposition: attachment; filename="'.basename($file).'"'); 
      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($file)); 
      ob_clean(); 
      flush(); 
      readfile($file); 


} 
+0

這對我來說非常完美。下載的文件沒有損壞。我用勞倫斯Cherone建議的PHP腳本,但下載的文件仍然腐敗。感謝Altair CA.並感謝所有。 – 2017-05-12 13:37:50

0

確保你沒有在最後一行後執行任何代碼readfile(FILE_NAME)

我不得不添加die();exit();的最後一行,因爲MVC框架繼續呈現readfile