私は簡単なファイルダウンロードスクリプトを使用しています:
if (file_exists($file)) {
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);
exit;
}
それは私のローカルサーバーで200mbまで動作しています。
私のウェブサイトでこのコードを試すと、200MBのファイルではなく173KBのファイルがダウンロードされます。
私はすべてをチェックし、いくつかのカスタムコードを作成しました(readfileの代わりにob関数とfreadを使用)が、大きなファイルをダウンロードできません。
ご回答ありがとうございます。
次のコードで私が抱えている問題の1つは、出力ストリームを制御できないことです。バックグラウンドで何が起こっているのかを正確に知らなくても、PHPで処理できます。
あなたがすべきことは、あなたが制御し、複製されたアクロスサーバーができる出力システムをセットアップすることです。
例えば:
if (file_exists($file))
{
if (FALSE!== ($handler = fopen($file, 'r')))
{
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: chunked'); //changed to chunked
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
//header('Content-Length: ' . filesize($file)); //Remove
//Send the content in chunks
while(false !== ($chunk = fread($handler,4096)))
{
echo $chunk;
}
}
exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";
これは基本的なことですが、試してみてください。
ここで私の返信も読んでください: file_get_contents => PHP致命的なエラー:許可されたメモリが使い果たされました
Readfileは長いファイルで問題が発生する可能性があるようです。 @Khezが尋ねたように、スクリプトの実行時間が長すぎる可能性があります。すばやくグーグルすると、ファイルをチャンク化する例がいくつかありました。
http://teddy.fr/blog/how-serve-big-files-through-phphttp://www.php.net/manual/en/function.readfile。 php#99406
特定のシナリオに対する1つの解決策は、PHPスクリプトを使用して、ダウンロードするファイルをインテリジェントに決定できることですが、ファイルをPHPから直接送信する代わりに、クライアントにリダイレクトを返すことができます。このリダイレクトには、処理される直接リンクが含まれます。 Webサーバーだけで。
これは、少なくとも2つの方法で実行できます。たとえば、PHPスクリプトがファイルを「ダウンロードゾーン」にコピーし、他のバックグラウンド/サービススクリプトによって「古い」ファイルから定期的に削除するか、実際の永続的な場所をに公開します。クライアント。
もちろん、各ソリューションの場合と同様に、欠点もあります。これは、ファイルを要求しているクライアント(curl、wget、GUIブラウザー)によっては、ユーザーが作成したリダイレクトをサポートしていない場合があり、もう1つでは、ファイルは外界に非常に公開されており、いつでも読み取ることができます。 PHPスクリプトの(アクセス)制御。
本当の解決策は、ファイルをクライアントに送信するためだけにPHPスクリプトを使用することを避けることです。それはやり過ぎであり、Webサーバーはこのタスクにより適しています。
おそらく、PHPを介してファイルを送信する理由があります。おそらく、ユーザーは最初に認証する必要がありますか?その場合は、 X-Accel-Redirect (nginxを使用している場合)または X-Sendfile (以前はX-LIGHTTPD-send-file)を使用する必要があります。 lighttpdで。
Apacheを使用している場合、 mod_xsendfile への参照がいくつか見つかりましたが、個人的に使用したことはなく、ホスティングを管理している場合はインストールされているとは思えません。
これらの解決策が受け入れられない場合は、お詫び申し上げますが、実際の問題に関する詳細情報が本当に必要です。そもそも、なぜこれらのファイルをPHPから送信するのですか?
スクリプト 長く実行できる 十分で、十分なメモリがあることを確認しましたか?
本当に出力バッファリングが必要ですか?