2011-11-05 23 views
1

私はサーバーからファイルをダウンロードするスクリプトを持っています。しかし、ファイルがダウンロードされると、それはjpgまたはpngファイルです。私はそれを見るためにどのプログラムでも開くことができないようです。 (Windowsフォトギャラリーまたは花火)fopen()、fread()、feof()を使用してファイルをダウンロードしています...ダウンロードしたファイルが壊れています

私はビデオファイル(avi)をダウンロードするとき。私はWindows Media Playerでそれを開くことはできませんが、私はvlcメディアプレーヤーで開くことができます。

私はいつもエラーメッセージを受け取り、ファイルまたはファイルを読み込めません。

ここにコードがあります。それは信頼できるものか、おそらくfsocketopenやcurlの使用を検討すべきですか?

私は、ウェブ上でより多くの答えを探しているヘッダーを変更しようとしましたが、運が悪いです。

誰かが間違ったことを考えていますか?

chmod("extensions_img/test.jpg",0755); 

$fullPath = "http://www.website_url.com/extensions_img/test.jpg"; 

if ($fd = fopen ($fullPath, "r")) { 

    $fsize = filesize("extensions_img/test.jpg"); 

    $path_parts = pathinfo($fullPath); 
    $ext = strtolower($path_parts["extension"]); 

    switch($ext) { 

     case "pdf": 
      $ctype = "application/pdf"; 
      break; 
     case "exe": 
      $ctype = "application/octet-stream"; 
      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": 
      $ctype = "image/jpg"; 
      break; 
     case "jpg": 
      $ctype = "image/jpg"; 
      break; 
     case "mp3": 
      $ctype = "audio/mp3"; 
      break; 
     case "wav": 
      $ctype = "audio/x-wav"; 
      break; 
     case "wma": 
      $ctype = "audio/x-wav"; 
      break; 
     case "mpeg": 
      $ctype = "video/mpeg"; 
      break; 
     case "mpg": 
      $ctype = "video/mpeg"; 
      break; 
     case "mpe": 
      $ctype = "video/mpeg"; 
      break; 
     case "mov": 
      $ctype = "video/quicktime"; 
      break; 
     case "avi": 
      $ctype = "video/x-msvideo"; 
      break; 
     case "src": 
      $ctype = "plain/text"; 
      break; 
     default: 
      $ctype = "application/force-download"; 
    } 

    header("Pragma: public"); 

    header("Expires: 0"); 

    header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 

    header("Cache-Control: private",false); 

    header("Content-type: " . $ctype); 

    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); 

    header("Content-Transfer-Encoding: binary"); 

    header("Content-length: $fsize"); 
    header("Cache-control: public"); //use this to open files directly 

    while(!feof($fd)) { 
     $buffer = fread($fd, 4096); 
    flush(); 
    } 
} 
fclose ($fd); 
+0

テキストファイルでそれを実行してから、ファイルの内容を調べてください。 PHPエラーメッセージがバッファに出力されている可能性がありますので、ファイルを破棄している可能性があります。 – prodigitalson

+0

ファイルが存在しないため、 '$ fsize'は常に' 0'です。 – KingCrunch

答えて

1

試してみてください。

while(!feof($fd)) { 
    echo fread($fd, 4096); 
    flush(); 
} 

あなたはとてもおそらくあなたのファイルが空のものをエコーされていませんか?

+1

なぜマイナス1? – samura

+0

thx samuraが問題を完全に修正しました=)... while(!feof($ fd)){ $ buffer = fread($ fd、4096); \t \t echo $ buffer; \t \t flush(); }あなたの方法... LIFESAVERはこの問題を永遠に処理していました。 thx ....とbtw donno何がマイナス1に起こった、たぶん私はacc。それを叫ぶ。回答のために –

0

正しく取得したファイルサイズを含むContent-length:ヘッダーを送信しています。

// You are opening a remote file: 
$fullPath = "http://www.website_url.com/extensions_img/test.jpg"; 

// You are retrieving the filesize of a local file that may or may not exist 
$fsize = filesize("extensions_img/test.jpg"); 

ので、ほとんどの場合、あなたが本当にContent-length次のようになります。

header("Content-length: 0"); 

...あなたは同じ名前の実際のローカルファイルを持っていない限り、あなたはそのファイルサイズを供給することがあります意図したリモートファイルではなく、

filesize() documentationによれば、いくつかのURLラッパーがサポートされています。

この機能は、一部のURLラッパーでも使用できます。サポートされているプロトコルとラッパーを参照して、ラッパーがstat()ファミリの機能をサポートする
を確認してください。

$fsize = filesize($fullpath); 
+0

ご返信ありがとうございます。私はもともと$ fsize = filesize($ fullpath)を設定しました。それは私に次のエラー(警告:filesize():http://www.website_url/extensions_img/test.jpgのstatが失敗しました)を投げます。しかし、もし$ fsize = filesize( "extensions_img/test.jpg");私は、ファイルのフルサイズがダウンロードされることに気付きました。 –

+0

@ MortenHgseth httpでファイルサイズを取得できない場合は、ファイルをダウンロードしてクライアントにストリーミングする前にローカルに保存する必要があります。 'Content-length'ヘッダーを省略するだけで動作しますか? –

+0

cURLを使用して、コンテンツを提供するサーバーからコンテンツ長を取得できる場合があります。 –

0

filesize($url)を使用すると、ファイルが2回ダウンロードされます。そしてfile_get_contentsまたはfpassthruがある場合、あなたが、とにかくfopen/freadを使用している理由は考え:これはまた、あなたの正しいMIMEタイプを取得する方法

$data = file_get_contents($url); 
$size = strlen($data); 
$mime = current(preg_grep('/^Content-Type:/i', $http_response_header)); 

はご注意を(だけで簡単にするためにheaderを経由して、全体stirngに沿って通過していません)。またはすべてのヘッダー。

+0

thx、私はfile_get_contentsとfpassthru関数を読み上げます。 –

+0

この場合、a)ファイル全体をメモリに読み込み、b)サーバがファイル全体を読み込むまで(メモリが非効率的で遅い)ユーザがファイルのダウンロードを開始できない場合は、 – StackOverflowed

関連する問題