2012-04-13 2 views
4

私はそれが基本的にダウンロードしたファイルが壊れているか破損しているのはなぜですか?

方法

はからそのファイルの名前と場所を2.gets「GET」とのファイルIDを1.gets私のダウンロード・スクリプト

と非常に奇妙な問題を抱えていますデータベース

は、ヘッダと、それをクライアントに3.sendsと

が、STをReadFile関数それはzipやRARファイルの場合と同様に ファイルサイズは右であり、それはOK

を開きますが、私はそれの内部で圧縮されたファイルを開くカント、私が取得するときにそれはです壊れたり

を損傷したように、そのファイルRangelyのいつも出てきますコードは、私もzipファイルを開くことができないはずです(少なくとも私はいけないと思う)問題を抱えていた場合cuzの奇妙なファイル破損してエラー

他の事は私がしましたですヘッダーを送信する前に、そのパスを使ってファイルを印刷して、すべてが正常であることを確認してください。

は、ファイルが

はそうすべてはここ

があるヘッダに私のコードを送信する前に細かいエラーなしで[OK]を私は、URL上のファイルのアドレスを入れて、ファイルをダウンロードしました

 $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

後のビューをレンダリングし続けているので、最後の行としてdie();またはexit();を追加する必要がありましたreadfile(FILE_NAME)

最後の行の後に実行するコードを持っていないことを確認してください高すぎる作品 – max

+0

@ダンブレー何のひどい編集、承認のためのコミュニティに恥ずかしい –

+0

@ LawrenceCheroneコードを動作させることについてはひどいですか?コードに ')'がありません。タイプミスでコードを残した方がよいと思いますか?紛失した ')'は人を混乱させ、多くの時間を無駄にする可能性がある。 –

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

これは私にとって完璧です。ダウンロードしたファイルは破損していません。私はLawrence CheroneがPHPスクリプトを提案したように使用しますが、ダウンロードしたファイルはまだ壊れています。 Altair CAに感謝します。そして、すべてに感謝します。 –

0

あなたは、私はMVCフレームワークがreadfile