0

現在取り組んでいる大規模なプロジェクト用の小さなダウンロード モジュールを構築していて、少し問題が発生しました。小さなファイルの場合は完全に機能しますが、ブラウザー (任意のブラウザー) が大きなファイルのダウンロードを開始すると、他のページと同じように単純に読み込まれ、最後の数秒で (サイズに関係なく) ファイル全体がほぼ瞬時に "ダウンロード" されます。私は HTTP 1.1 標準を何度も確認してきましたが、その文字どおりに従っているようです。すぐに思い浮かぶのは、PHP が実際にクライアントにデータを送信するときです。答えは、スクリプトの実行時であるべきです。私は、この原則をデバッグ用の他の長いスクリプトで使用しています。

関連するコードは次のとおりです (もちろん他にもたくさんありますが、ヘッダーと出力が実際に送信される場所は次のとおりです。

header("Content-Type: application/force-download");
header("Content-length: $size");
header('Content-Disposition: attachment; filename="'.$fileData['name'].'"');    
for ($i=0; $i<$size; $i+=$step)
{
    $content = fread($file, $step);
    if ($content === false)
        $content = "";

    echo $content;
}
die();

何か案は?これは、このブロックを長い間見つめていてもわからない明らかな問題だと感じています。

前もって感謝します!

4

2 に答える 2

0

ここでこれを試してください。渡されたファイルがディレクトリであるか見つからない場合、この関数は false を返します。また、ダウンロードを中断しないように、ファイル名からスペースを削除します。変更することでダウンロード速度を制限することも可能で、10242GB を超えるファイルを処理します。

<?php 
function download($file){
    if (file_exists($file)) {
        if(is_dir($file)){return false;}
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.str_ireplace(' ','_',basename($file)).'"');
        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: '.sprintf("%u", filesize($file)));

        @ob_clean();
        $handle = fopen($file, "rb");
        $chunksize=(sprintf("%u", (filesize($file))/1024));

        set_time_limit(0);
        while (!feof($handle)) {
            echo fgets($handle, $chunksize);
            flush();
        }
        fclose($handle);
        die;
    }else{return false;}
    return;
}
?>
于 2012-06-14T15:59:31.733 に答える
0

ツールを使用するだけで、車輪の再発明はやめてください。pecl_httpは、しばらく前から存在しています。

<?php
http_send_content_disposition("document.pdf", true);
http_send_content_type("application/pdf");
http_throttle(0.1, 2048);
http_send_file("../report.pdf");
?>

このコード サンプルは高速で堅牢で、複数の機能ボーナスを提供します。

  • 帯域幅調整
  • キャッシュとヘッダーの管理
  • 部分的で再開可能なダウンロード
于 2012-06-14T16:09:37.257 に答える