2013-06-28 9 views
5

.mp4ファイルをダウンロードしようとしています。 (約1.3GBサイズ)。私は、以下の使用してい : PHPファイルからの強制ダウンロード

<?php 
$path = "video.mp4"; 
header('Accept-Ranges: bytes'); // For download resume 
header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
header('Content-Description: File Transfer'); 
header('Content-Disposition: attachment; filename="'.basename($path).'"'); 
header('Content-Length: ' . filesize($path)); // File size 
header('Content-Transfer-Encoding: binary'); // For Gecko browsers mainly 
header('Content-Type: application/octet-stream'); 
header('Expires: 0'); 
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT'); 
header('Pragma: no-cache'); 
ob_clean(); 
flush(); 
readfile($path); 

私は私のPHPファイルを開き、Firefoxは「保存する」メニューがポップアップ表示されます。サイズは正しく見えます。 私はデスクトップに[名前を付けて保存]を押します。最終的にダウンロードされるファイルは、400MB(330,463,440)くらいのランダムなサイズで表示されます。

レスポンスヘッダは、次のとおりです。

Connection: Keep-Alive 
Content-Disposition: attachment; filename="//www.frederikspang.dk/elevgallavideo.mp4" 
Content-Length: 1422778850 
Content-Type: video/mp4 
Date: Sun, 30 Jun 2013 22:12:30 GMT 
Keep-Alive: timeout=10, max=50 
Pragma: public 
Server: Apache 
content-transfer-encoding: binary 
+1

実行制限時間を過ぎている可能性があります。ダウンロードはいつも同じ時間後に停止しますか? –

+0

再開可能なファイルのダウンロードにはこれよりも多くのコードが必要です。 'Accept-Range 'を削除する必要があります。参照:http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file –

+0

実際に出力バッファリングを使用していますか?そうでなければ、おそらくob_clean()とflush()は必要ありません。なぜなら、readfileコマンドはクライアントに直接データを出力するからです。 – dethtron5000

答えて

0
<?php 
$filename = "theDownloadedFileIsCalledThis.mp4"; 
$myFile = "/absolute/path/to/my/file.mp4"; 

// Add bellow code for mime type 
$ext=strtolower(substr($fl,strrpos($myFile,"."))); 
$mime_types = array(
      '.txt' => 'text/plain', 
      '.htm' => 'text/html', 
      '.html' => 'text/html', 
      '.php' => 'text/html', 
      '.css' => 'text/css', 
      '.js' => 'application/javascript', 
      '.json' => 'application/json', 
      '.xml' => 'application/xml', 
      '.swf' => 'application/x-shockwave-flash', 
      '.flv' => 'video/x-flv', 

      // images 
      '.png' => 'image/png', 
      '.jpe' => 'image/jpeg', 
      '.jpeg' => 'image/jpeg', 
      '.jpg' => 'image/jpeg', 
      '.gif' => 'image/gif', 
      '.bmp' => 'image/bmp', 
      '.ico' => 'image/vnd.microsoft.icon', 
      '.tiff' => 'image/tiff', 
      '.tif' => 'image/tiff', 
      '.svg' => 'image/svg+xml', 
      '.svgz' => 'image/svg+xml', 

      // video 
      '.3gp' => 'video/3gpp', 
      '.3g2' => 'video/3g2', 
      '.avi' => 'video/avi', 
      '.mp4' => 'video/mp4', 
      '.asf' => 'video/asf', 
      '.mov' => 'video/quicktime', 
     ); 

if (array_key_exists($ext, $mime_types)){ 
    $mm_type=$mime_types[$ext]; 
}else{ 
    $mm_type="application/octet-stream"; 
} 
$mm_type="application/octet-stream"; 

header("Cache-Control: public, must-revalidate"); // Avoid this line 
header("Pragma: public"); // Add this line 
header("Pragma: hack"); // Avoid this line 
header("Content-Type: " . $mm_type); 
header("Content-Length: " .(string)(filesize($myFile))); // Avoid this line 
header('Content-Disposition: attachment; filename="'.$filename.'"'); 
header('Content-Length: ' . filesize($myFile)); // Add this line 
header("Content-Transfer-Encoding: binary\n"); 
ob_clean(); // Add this line 

readfile($myFile); 

?> 
+0

非常に不明確な回答です。それはうまく説明されていません。 "避けてください"と "追加する"、なぜそれを詳述してください。 –

+0

MIMEタイプのリファレンスは有用であり、ヘッダー宣言が意味をなす...「避ける」とは明らかに「使用しない」を意味し、「追加する」は「追加する」を意味する。彼がやったことは、理由についてのより良い説明が提供されました – zgr024

+0

'$ mm_type =" application/octet-stream "をとにかく設定しようとしているのなら、すべてのMIMEタイプのガベージはどうですか? –

1

これは難しいです - ほとんどのPHPの設定は30秒後に失敗します。あなたがphp.iniを所有している場合は、それをより長い制限に変更することができます。しかし、それでも価値があるのでしょうか?つまり、ファイルが大きくなったりネットワークが遅くなったりする可能性があります。もう一度タイムアウトになるでしょう。

大きなサイズのファイルを小さな塊でダウンロードする理由は、Half Crazedはそのコードを示しています。THIS回答(その1つだけではなく、クライアントが転送をネゴシエートする方法の1つを考慮していますが良いスタート)。

たとえば、Mega.co.nzは新しいhtml5機能を使用します。チャンクを使ってブラウザでファイルをダウンロードし、ユーザーのファイルに参加してから、ブラウザのディスクスペースからダウンロードします。ファイルの再開、ファイルの一時停止などが可能です。 (申し訳ありません - それは非常に大きく、複数の言語(php、js)を含むので、コードはありません)。

PS:これは一度、メモリに8KiBの部分だけをファイル全体をロードし、ユーザーにそれらを送信しません

$handle=fopen($path, 'rb'); 
while (!feof($handle)) 
{ 
    echo fread($handle, 8192); 
    flush(); 
} 
fclose($handle); 

:あなたにreadfile($path);を変更。

+0

これは非常に真実ですが、それはApache2のKeep-Aliveでしたが、それは十分に高くありませんでした。 (ちょうどこの質問を再度見た、私はあなたに答えを与えると思った) –

+0

遅く答えて申し訳ありませんが、キープアライブは他の理由で使用されています...ほとんどのサーバーは60秒後にphpを殺すでしょう - 殺されるだろう)。そして、その限界を持ち上げることは、しばしば賢明ではない – Seti

関連する問題