PHPを使用して長期タスクを実行する場合、ユーザーがブラウザを閉じたり、リクエストを積極的に切断したり、PHPスクリプトが中止される状況に遭遇することがよくあります。これは、バックエンドの長期的な実行または継続的な処理を必要とするスクリプトにとって非常に致命的です。では、ユーザーが切断されたときにスクリプトが中止されるのを防ぐ方法は?答えは、 INGRORE_USER_ABORT()関数を使用することです。
INGRORE_USER_ABORT()は、PHPが提供する関数であり、クライアントが切断されたときにスクリプトが実行され続けるかどうかを設定します。
ignore_user_abort(true);
真のパラメーターが渡されると、実行が完了またはタイミング/アクティブに終了するまでユーザーがブラウザを閉じても、PHPスクリプトが実行され続けます。
非同期タスクを処理します
背景キュー処理
タイミングタスクシミュレーション実行
ファイル生成またはビッグデータのエクスポート
状態の一貫性を維持する必要がある舞台裏の操作
実用的な例を示すために、システムバックアップ機能を開発している場合、ユーザーが「バックアップを開始」をクリックした後、スクリプトは10分以上実行する必要があります。ユーザーがブラウザを閉じると、デフォルトでスクリプトが中止され、バックアップタスクが失敗します。また、 INGRORE_USER_ABORT(TRUE)を介して、ユーザーがページを離れても、バックアップが完了するまでスクリプトはサーバー上で実行され続けます。
典型的な長いタスク処理コードの例は次のとおりです。
<?php
ignore_user_abort(true); // ユーザーが接続を破っても実行を続けます
set_time_limit(0); // スクリプトの実行時間制限をキャンセルします
file_put_contents('log.txt', "ミッション開始時間:" . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
// 長期的なタスクをシミュレートします
for ($i = 1; $i <= 10; $i++) {
file_put_contents('log.txt', "第 {$i} 段階的な実行...\n", FILE_APPEND);
sleep(5); // シミュレーションの各ステップの時間がかかります
}
file_put_contents('log.txt', "タスクの完了時間:" . date('Y-m-d H:i:s') . "\n", FILE_APPEND);
?>
たとえば、CurlまたはAjaxリクエストを使用してこのスクリプトを呼び出すことができます。
fetch("https://gitbox.net/run-task.php");
リクエストを送信した後にユーザーがブラウザを閉じたとしても、スクリプトは完全に実行されます。
ログの書き込みや特定の動作の中止など、ユーザーが切断された後に論理処理を行う場合は、 connection_aborted()関数を使用して検出できます。
if (connection_aborted()) {
file_put_contents('log.txt', "ユーザー接続が中断されました\n", FILE_APPEND);
}
INGRORE_USER_ABORT(TRUE)で使用すると、より柔軟に割り込みと非壊死を処理できます。
Ingrore_user_abort()を使用しても、すべての例外を無視できるという意味ではなく、割り込みはサーバー側(nginx、Apache構成など)またはPHPスクリプト自体(メモリ制限など)からも発生する可能性があります。
最大実行時間制限をキャンセルするために、 set_time_limit(0)を同時に使用することをお勧めします。
スクリプトがデータをクライアントに出力する場合、 ob_start()を使用してロジックの前にバッファリングを有効にして、出力動作によって引き起こされる接続の問題を回避してください。
PHPで長いタスクを処理する場合、 Ingrore_user_abort(true)を使用することは、スクリプトが中央のユーザーによって中断されないようにする効果的な方法です。サーバー側でタスクが完全に実行され、システムの安定性と信頼性が向上することを保証できます。これは、バックアップ、プッシュ、エクスポートなどのタスクを含むバックグラウンドスクリプトの非常に実用的なトリックです。