私は疑問に思っていました-最大10,000行を更新でき、完了するまでに数秒かかる可能性のあるコードスニペットを書いたので、ファイルがajaxリクエストを介してアクセスされたときにポストクエリがphpファイルに送信され、次にブラウザが閉じられていますが、ファイルは完全に実行されていますか? リクエストを完了するのに約 25 秒かかると仮定すると、ユーザーは 25 秒待たない可能性があります。このファイルを "ping" して、mysql クエリが実行されているときにユーザーがブラウジングするか、ブラウザ ウィンドウを閉じるだけで十分ですか?
5 に答える
クライアントが切断された後でもスクリプトを実行し続けるには、ignore-user-abortを使用します。
ignore_user_abort(true);
set_time_limit(0);
connection_statusを使用して、接続が切断されたかどうかを追跡 できます
if (connection_status()!=0) { //connection disconnected
あなたの質問に対する答えは次のとおりです。
http://www.php.net/manual/en/features.connection-handling.php
リクエストには 3 つの部分があります
- Web サーバーに接続されたブラウザー
- サーバーによって実行される PHP スクリプト
- DB サーバーで実行されているクエリ
ブラウザを閉じると、サーバーとの接続が切断されます。サーバーは、開始された PHP スクリプトを強制終了する場合としない場合があります (PHP が apache モジュールとして実行されている場合、ignore_user_abort が呼び出されない限り、強制終了されます)。また、Web サーバーには要求の時間制限があり、スクリプトを強制終了するか、クライアントに接続タイムアウト メッセージを送信するだけで、スクリプトを強制終了せずに、ブラウザーに何も送信する機会を与えない場合があります。
ここが厄介な部分です。更新はデータベースで実行されており、Web サーバーや PHP によって強制終了されることはありません。
したがって、達成したいのは、クエリを実行している PHP スクリプトに ping を実行することですが、クライアントは結果を待ちません。クエリ自体を非同期にする (PHP スクリプトがクエリを待機しないようにする) 必要がある場合とそうでない場合がありますが、たとえば content-length 0 を送信し、出力をフラッシュすることによって、要求が満たされていることをクライアントに伝える必要があります。 (実際にはhttpヘッダー)、ignore_user_abortでPHPを実行しているため、実行が続行されます。
通常はいいえですが、スクリプトはABORTED
ステータスを渡します。
接続処理に関するマニュアル ページの詳細: http://www.php.net/manual/en/features.connection-handling.php
PHP の内部では、接続ステータスが維持されます。次の 3 つの状態があります。
0 - 通常
1 - 中止
2 - タイムアウト
PHP スクリプトが正常に実行されている場合、NORMAL 状態がアクティブです。リモート クライアントが切断すると、ABORTED 状態フラグがオンになります。通常、リモート クライアントの切断は、ユーザーが STOP ボタンを押すことによって発生します。
ブラウザーを閉じるとすぐに、応答を取得する前にサーバーから切断されます。この状態でさまざまなサーバーがどのように動作するかは正確にはわかりませんが、ほとんどのサーバーは、リクエストに応答するために取り組んでいるスレッドを中止すると思います。
さらに、ファイル I/O やデータベース操作など、さまざまな操作で状況が異なる場合があります。それがアトミックなデータベース操作である場合、私の推測では、どのようにでも完了します。