タイトルが変なのは、以下の部分を短い文でどう要約すればいいのか分からないからです。 PHP 開発者が検索エンジンを通じてこの入門書をもっと簡単に見つけられることを願っています。
今回の中心的な内容は、ignore_user_abort 関数を中心に展開します。
Web 開発を行う人なら誰でも、ブラウザとサーバー間の接続と通信が HTTP プロトコルを介して行われることを知っています。これは、リクエストとレスポンスのモデルに基づいたプロトコルです。 URL経由のブラウザ 特定のサーバーに対してリクエスト (Request) を開始し、Web サーバーはリクエストを受信してプログラムを実行し、HTTP に準拠した文字列で応答します (Response)。 プロトコルの形式には、HEAD と BODY の 2 つの部分があります。
ウェブさん、問題がありますか? サーバーがプログラムを実行する場合、数ミリ秒で完了する場合もあれば、数分以内に完了しない場合もあります。プログラムの実行が遅い場合、ユーザーはそれ以上待つ忍耐力がなくなり、ブラウザを閉じる可能性があります。このとき、サーバーは接続ステータスの変更の通知を受け取ります。 HTTP? は最上位のプロトコルであり、その下に TCP プロトコルの層があり、接続が中断されたことを認識します。接続が切断されると、サーバー側プログラムはすぐに実行を停止します。
ここで問題の核心に入ります。サーバー側プログラムは実行をすぐに停止します。このプログラムが情報を読み取るだけであれば問題ありませんが、停止すると情報は読み取られなくなります。書かれたプログラムの場合はどうなるでしょうか?たとえば、ユーザーがテキストを送信する場合、サーバーの設計はより複雑になり、テーブルの 1 つが別のプロセスによってロックされているなどの理由により、複数のテーブルを同時に更新する必要がある可能性があります。 、この時点で、ユーザーが閲覧デバイスを閉じると、プログラムは待機せずに直接終了します。その結果、この情報は不完全に保存されます。
具体的な例を挙げると、ユーザーが送信したテキストを 4 つのテーブル A、B、C、D に書き込む必要があります。2 つのテーブル A と B への書き込みは 0.1 ミリ秒で完了しますが、C テーブルが別のプロセスによってロックされている場合、現在のプロセスは待機する必要があり、ユーザーがブラウザを閉じると、テーブル A と B に新しいコンテンツが存在します。一方CとD テーブルにはそのような内容が存在しないため、データの整合性に関する重大な問題が発生します。
データベース トランザクションを使用して状態をロールバックすることはできますが、結果としてユーザーの送信は無効になります。
私が望んでいるのは、ユーザーが送信した限り、正常に保存されることです。予期せぬ状況により実行時間が長すぎる可能性がありますが、ユーザーがブラウザを閉じても問題ありません。
そこで、ignore_user_abort 関数を見つけました。
ignore_user_abort(1) が呼び出されると、ユーザー出口を無視するフラグが設定されます。つまり、プログラム内で呼び出されない限り、プログラムは何があっても最後まで実行される必要があります。 出口。
実際には、別の関数 register_shutdown_function があり、これは関数またはメソッドを登録し、プログラムの終了時にそれを呼び出すことができます。 JavaScript の onunload および onbeforeunload イベント。
ここに中国語版の PHP マニュアルを引用しました 関連コンテンツ:
第 40 章 接続処理
注: 以下は PHP 3.0.7 以降に適用されます。
PHP 内部では、システムは接続ステータスを維持しており、そのステータスには 3 つの状況が考えられます。
0 - 通常
1 - ABORTED (異常終了)
2 - TIMEOUT (タイムアウト)
PHP スクリプトが NORMAL 状態で正常に実行されている場合、接続は有効です。リモートクライアントが切断されると中止される ステータスフラグがオンになります。リモート クライアント接続の中断は通常、ユーザーが [STOP] ボタンをクリックしたことによって発生します。接続時間が PHP の制限時間を超えた場合 (set_time_limit() を参照) 機能)、TIMEOUT状態のフラグがオンになります。
クライアントが切断されたときにスクリプトを終了する必要があるかどうかを決定できます。リモート ブラウザがスクリプトの出力を受け入れない場合でも、スクリプトを完全に実行すると便利な場合があります。デフォルトでは、リモート クライアント接続が失われたときにスクリプトが終了します。この処理は次のように行うことができます php.ini のignore_user_abort、または Apache .conf 設定の対応する「php_value」 ignore_user_abort" とignore_user_abort() 関数。PHP がユーザーの中断を無視するように指示されていない場合、スクリプトは渡されない限り中断されます。 register_shutdown_function() はシャットダウン トリガー関数を設定します。このシャットダウン トリガー機能により、リモート ユーザーが [STOP] をクリックすると、 ボタンを押した後、スクリプトが再度データを出力しようとすると、PHP は接続が中断されたことを検出し、クローズ トリガー関数を呼び出します。
スクリプトは、組み込みのスクリプト タイマーによって中断される場合もあります。デフォルトのタイムアウト制限は 30 秒です。この値は、php.ini で max_execution_time を設定することによって設定できます。 Apache .conf 設定または set_time_limit() の対応する「php_value max_execution_time」パラメータ 変更する機能。カウンタがタイムアウトすると、上記の接続中断状況と同様にスクリプトが終了し、事前に登録されたシャットダウン トリガー関数もこの時点で実行されます。このシャットダウントリガー関数では、次の関数を呼び出すことができます。 connection_status() 関数を使用して、タイムアウトによってシャットダウン トリガー関数が呼び出されたかどうかを確認します。タイムアウトによりシャットダウン トリガー関数が呼び出された場合、関数は 2 を返します。
注意すべき点の 1 つは、ABORTED 状態と TIMEOUT 状態が同時に有効になる可能性があるということです。これは、PHP にユーザー終了アクションを無視するように指示する場合に可能です。 PHP ユーザーが切断されてもスクリプトがまだ実行されている状況を引き続き認識します。実行時間制限に達すると、スクリプトは終了し、設定されたシャットダウン トリガー関数も実行されます。この時点で、関数が見つかります connection_status() は 3 を返します。
PHP の公式 Web サイトのオンライン ドキュメントにはオリジナルの英語の説明があり、これも非常に貴重なリンクです。
?http://www.php.net/manual/en/features.connection-handling.php
転載元: http://www.leakon.com/archives/22