時間制限を回避するための優れたトリックがありますが、適切に行わないとサーバーの遅延が発生する可能性があります。このスクリプトに基づいて、純粋な PHP CRON の代替案を作成しました。
何をするかというと、HTTP クライアントを切断しますが、スクリプトは実行し続けます。これが最も重要です。そうすれば、スクリプトは istelf でスタックすることなく、自分自身を呼び出すことができます。
これを行うには、http ヘッダー Content-Length を送信することが重要です。
<?php
ignore_user_abort (true); //Tells PHP to ignore connection state
ob_start();
echo "Loop started\n";
$size = ob_get_length();
header("Content-Length: $size"); //Send exact output size to make sure client disconnects
header("Connection: close"); //Tells client to disconnect
ob_end_flush();
ob_flush();
flush(); //Clean all buffers
if(session_id()!="")
session_write_close(); //Close the session so that the user can use other scripts on the site
/*Here, the script runs even if client is connected*/
?>
さて、非常に危険な再帰部分があります。複数のスレッドを回避するために、スクリプトが既に実行されていることをスクリプトに伝えるファイルを作成する必要があります。このような:
if(file_exists("secure_key"))
exit;
else
file_put_contents("secure_key",time());
一部のデータを同期していると述べたため、同期プロセスに関する情報を保存するために、もう 1 つのファイル (または MySql テーブル) が必要になる場合があります。これにより、おそらくAJAXを使用して、リクエストの進行状況をユーザーに通知できるようになります。これにより、アプリケーション全体が非常にプロフェッショナルに見えます :)
ご存知かもしれませんが、同期しているのが FOR または WHILE ループの場合、開始時刻を一定に保存することも優れているため、問題なく終了して保存できます。
define("STARTTIME",time()); //Right now
define("MAXTIME",ini_get('max_execution_time')); //Max execution time
define("SAFE_EXIT_TIME", 4); //4 seconds to save & quit
/*preparation*/
while(time()-(STARTTIME-SAFE_EXIT_TIME)<MAXTIME) {
/*Synchronize*/
}
unlink("secure_key"); //delete the antistuck file
get_headers(/*scriopt url*/); //call itself
exit; //quit