ファイルをまとめてダウンロードできるWebサイトのPHPページを作成しています。 zipのファイルサイズは、数MBから100MBの範囲であればどこでもかまいません。私のPHPスクリプトはzipファイルを一時ディレクトリに作成し、ファイルの内容をブラウザに書き出します。これが完了すると、スクリプトはMySQLデータベースのダウンロードカウンタを更新し、一時ディレクトリからzipファイルを削除します。大容量ファイルのダウンロード後にPHPスクリプトが終了しない
これは、30秒以上かかる大規模なzipダウンロードが発生するまで、すべて正常に動作します。 php.iniファイル内のmax_execution_time
は30に設定されていますが、これは意味がありますが、set_time_limit(0)
を使用するか、max_execution_time
を使用しても同じ結果が得られます。 zipファイルはブラウザから正常にダウンロードされますが、データベースは更新されず、サーバー上の一時的なzipファイルは削除されないため、スクリプトは後で停止するようです。
これはApacheとPHP 5.2のLinux環境です。
このウェブサイトはGoDaddyでホストされていますので、スクリプトで実行できる時間制限の変更に制限があるのかどうかはわかりませんが、基本的には完了するまで無期限に実行します。
制限時間や回避策を設定できない理由についてのご意見はありますか?
は、ここに私のコードです:
<?php
// Don't stop the script if the user
// closes the browser
ignore_user_abort(true);
set_time_limit(0);
// Generate random name for ZIP file
$zip_file = "";
$characters = "abcdefghijklmnopqrstuvwxyz";
do
{
$zip_file = "tmp/";
for ($p = 0; $p < 10; $p++)
$zip_file .= $characters[mt_rand(0, strlen($characters))];
$zip_file .= ".zip";
} while (file_exists($zip_file));
// Prepare ZIP file
$zip = new ZipArchive();
/* Open and add files to ZIP (this part works fine)
.
.
.
*/
// Close and save ZIP
$zip->close();
// Check browser connection
if (connection_status() == 0)
{
// Send ZIP
header("Content-Type: application/zip");
header("Content-Length: " . filesize($zip_file));
header("Content-Disposition: attachment; filename=Download.zip");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
// Save and then delete file
//readfile($zip_file);
if ($file = fopen($zip_file, "r"))
{
// Set buffer size
$buffer_size = 1024 * 8;
// While we're still transmitting
// send over bytes!
while(!feof($file) && (connection_status() == 0))
{
print(fread($file, $buffer_size));
flush();
usleep(10000); //<!-- Download speed cap
}
// Close file descriptor
fclose($file);
}
}
/* Update database download counter if connection_status() == 0
.
.
.
*/
// Delete the file
unlink($zip_file);
?>
UPDATE:私はちょうど私のローカルWebサーバーから別のダウンロードをやってみましたし、ダウンロード時間を遅くするために10000にusleep
コマンドを格上げ。ダウンロード時間の合計が1分を少し超えてデータベースが更新され、ファイルが/ tmpから削除されました。私のローカル環境では、Windows 7のボックスでApacheとPHP 5.3を使ってEasyPHPを実行します。これはGoDaddyと関係があるようだ。
max_execution_time
また、set_time_limit
がスクリプトから呼び出された後、結果がそれぞれ30と0になったので、GoDaddy側で何が起こっているのか分かりません。
なぜディスクに一時ファイルを生成しないのですか? –
なぜあなたはApacheの大規模なダウンロードを扱わないのですか? PHPスクリプトは、タイムアウトする可能性のあるリンクに300のスタイルに対応することができます。 –
PHPは安全モードで動作していますか? GoDaddyのホスティングについてはわかりません。 –