検索

PHP のライフサイクルを調べる

Jul 28, 2020 pm 04:38 PM
phpライフサイクル

PHP のライフサイクルを調べる

PHP ライフ サイクルを学ぶ

PHP のライフ サイクルは非常に複雑なプロセスであり、そのライフ サイクルは、使いこなしたい人が習得する必要があります。それ。主な内容は次のとおりです。

PHP の起動。 CLI または FPM を実行している場合は、C main() が実行されます。 apxs2 SAPI (Apache 2) のように、ネットワーク サーバーへのモジュールとして実行する場合、Apache の起動直後に PHP が起動し、そのモジュール (PHP もその 1 つ) の起動シーケンスの実行を開始します。スタートアップは内部的に Module Startup Step と呼ばれます。 MINIT ステップとも略します。

PHP が開始されると、1 つまたは複数のリクエストの処理を待機します。 PHP CLI について話すとき、リクエストは 1 つだけです。実行する現在のスクリプトです。しかし、Web 環境について話す場合、それは PHP-FPM または Web サーバー モジュールである必要があります。PHP は複数のリクエストを次々に処理できます。すべては Web サーバーの構成方法によって異なります。無制限の数のリクエストを処理するように指示することも、プロセスをシャットダウンしてリサイクルする前に特定の数のリクエストを処理するように指示することもできます。 PHP は、新しいリクエストがスレッドで処理されるたびに、リクエスト開始ステップを実行します。これを #RINIT と呼びます。

関連する学習の推奨事項: PHP プログラミングの入門から熟練度まで

リクエストが処理され、(おそらく) コンテンツが生成されました。リクエストを閉じて、別のリクエストを処理する準備をします。クローズ要求は、リクエストクローズステップを呼び出します。これを #RSHUTDOWN と呼びます。 ·

X リクエスト (1 つ、数十、数千など) を処理した後、PHP は最終的に自動的にシャットダウンして終了します。 PHP プロセスのシャットダウンは、モジュール シャットダウン ステップと呼ばれます。略称は MSHUTDOWN です。

これらの手順を描くことができれば、次のようになります:

PHP のライフサイクルを調べる

並列モデル

CLI 環境では、何でも簡単です。 : プロセスはリクエストを処理します。別の PHP スクリプトを開始して終了します。 CLI 環境は Web 環境を特殊化したものであり、より複雑です。

複数のリクエストを同時に処理するには、並列モデルを実行する必要があります。 PHP には 2 つのタイプがあります。

  • #プロセスベースのモデルプロセスベースのモデル
  • #スレッドベースのモデルスレッドベースのモデル

Use プロセス モデルに基づいて、オペレーティング システムは各 PHP インタープリターを独自のプロセスに分離します。このモデルは Unix では非常に一般的です。各リクエストは独自のプロセスに送られます。 PHP-CLI、PHP-FPM、および PHP-CGI はこのモデルを使用します。

スレッドベースのモデルでは、各 PHP インタープリターは、スレッド ライブラリを使用してスレッドに分離されます。このモデルは主に Windows オペレーティング システムで使用されますが、ほとんどの Unix でも使用できます。 PHP とその拡張機能を ZTS モードで構築する必要があります。

これはプロセスベースのモデルです:

PHP のライフサイクルを調べる

これはスレッドベースのモデルです:

PHP のライフサイクルを調べる

Note

拡張機能開発者にとって、PHP のマルチプロセス モジュールは選択肢にはなりません。それをサポートする必要があります。拡張機能がスレッド環境 (特に Windows 上) で実行できるようにする必要があり、そのようにプログラムする必要があります。

PHP 拡張フック

ご想像のとおり、PHP エンジンは複数のライフサイクル ポイントで拡張機能をトリガーします。これらを フック関数 と呼びます。拡張機能は、エンジンに登録するときに関数フックを宣言することで、特定のライフサイクル ポイントへの関心を宣言できます。
これらのフックは、PHP 拡張構造 (zend_module_entry 構造) を分析すると明確にわかります。

struct _zend_module_entry {
        unsigned short size;
        unsigned int zend_api;
        unsigned char zend_debug;
        unsigned char zts;
        const struct _zend_ini_entry *ini_entry;
        const struct _zend_module_dep *deps;
        const char *name;
        const struct _zend_function_entry *functions;
        int (*module_startup_func)(INIT_FUNC_ARGS);        /* MINIT() */
        int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS);   /* MSHUTDOWN() */
        int (*request_startup_func)(INIT_FUNC_ARGS);       /* RINIT() */
        int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS);  /* RSHUTDOWN() */
        void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS);     /* PHPINFO() */
        const char *version;
        size_t globals_size;
#ifdef ZTS
        ts_rsrc_id* globals_id_ptr;
#else
        void* globals_ptr;
#endif
        void (*globals_ctor)(void *global);                /* GINIT() */
        void (*globals_dtor)(void *global);                /* GSHUTDOWN */
        int (*post_deactivate_func)(void);                 /* PRSHUTDOWN() */
        int module_started;
        unsigned char type;
        void *handle;
        int module_number;
        const char *build_id;
};

次に、コードにどの種類のフックを記述する必要があるかを見てみましょう。

モジュールの初期化: MINIT()

これは、PHP プロセスの起動ステップです。拡張された MINIT() では、後続の各リクエストに必要な永続オブジェクトまたは情報をロードして割り当てます。それらのほとんどは読み取り専用オブジェクトとして割り当てられます。

MINIT() では、スレッドやプロセスがまだポップアップしていないため、保護なしでグローバル変数に完全にアクセスできます。また、リクエストがまだ開始されていないため、リクエストにバインドされたメモリを割り当てることはできません。 MINIT() ステップでは Zend のメモリ管理割り当てを使用することはありませんが、永続的な割り当てが使用されます。 emalloc() ではなく、pemalloc() です。そうしないとクラッシュが発生します。

MINIT() では、実行エンジンがまだ開始されていないため、特別な注意を払わずにその構造にアクセスしようとしないでください。

拡張機能の INI エントリを登録する必要がある場合は、MINIT() が正しいアプローチです。

後で使用するために読み取り専用の zend_string を登録したい場合は、永続的割り当てを使用してください。

割り当てる必要があるオブジェクトがリクエストの処理中に書き込まれる場合は、それらのメモリ割り当てをそのリクエストのスレッド固有のプールにコピーする必要があります。グローバル空間に安全に書き込むことができるのは、MINIT() のみであることに注意してください。

メモリ管理、割り当て、およびデバッグは、メモリ管理の章の一部です。

php_module_startup() 関数では、MINIT()zend_startup_modules() を通じてトリガーされます。

モジュール終了: MSHUTDOWN()

これは、PHP プロセスの終了ステップです。基本的には簡単です。ここでは、MINIT() で使用したものとは逆のことを実行します。リソースを解放したり、INI 設定の登録を解除したりします。

もう一度注意してください: 実行エンジンは閉じられているため、ここではその変数にアクセスしないでください。

ここではリクエストが必要ないため、リソースを解放するために Zend Memory Management の efree() または同様の関数を使用しないでください。ただし、永続的な割り当てを解放するには、pefree ( )

php_module_shutdown() 関数では、MSHUTDOWN()zend_destroy_modules()zend_shutdown() によってトリガーされます。

リクエストの初期化: RINIT()

先ほど確認したリクエストは、PHP がここで処理します。 #RINIT() では、その正確なリクエストを処理するために必要なリソースを指示します。 PHP は、メモリ管理機能を提供するシェアードナッシング アーキテクチャです。

RINIT() で、動的メモリを割り当てる必要がある場合は、Zend メモリ マネージャーを使用します。 emalloc() を呼び出します。 Zend メモリ マネージャーは、ユーザーが割り当てたメモリを追跡し、リクエストが閉じられたときに、これを忘れた場合はリクエストにバインドされたメモリを解放しようとします (これは行うべきではありません)。

ここでは、永続的な動的メモリ、つまり libc の malloc() や Zend の pemalloc() をリクエストしないでください。ここで永続メモリをリクエストし、それを解放するのを忘れると、PHP が処理するリクエストが増えるにつれてリークが蓄積し、最終的にはプロセスがクラッシュし (カーネル OOM)、マシンのメモリが不足します。

また、ここではグローバル空間に書き込まないように注意してください。選択した並列モデルとして PHP がスレッド内で実行される場合、各スレッド プールのコンテキスト (すべてのリクエストが並行して処理される) を変更することになり、メモリをロックしないと競合状態がトリガーされる可能性もあります。全体像を把握したいなら、彼らを守らなければなりません。

グローバル スコープ管理については、専用の章で説明します。

php_request_startup() 関数では、RINIT()zend_activate_module() によってトリガーされます。

リクエスト終了: RSHUTDOWN()

これは、PHP リクエスト終了ステップです。 PHP はリクエストの処理を終えたところです。今度は、シェアードナッシング アーキテクチャとしてメモリの一部をクリーンアップします。後続のリクエストでは、現在のリクエストの内容を何も覚えてはいけません。それは簡単です。基本的に、ここで RINIT() が使用していることと逆のことを行うことになります。リクエストによってバインドされているリソースを解放します。

ここではリクエストを使用しているため、Zend メモリ マネージャーの efree() などを使用してリソースを解放する必要があります。解放するのを忘れてリークが発生した場合、デバッグ ビルドでメモリ マネージャーがプロセス stderr 上のリークしたポインターをログに記録し、それらを解放します。

ユーザー領域のシャットダウン関数 (register_shutdown_function()##) を実行した後、RSHUTDOWN()

が呼び出されます。 #)
  • 各オブジェクト デストラクターを呼び出した後 #PHP 出力バッファーをフラッシュした後 #max_execution_time を無効にした後
  • #php_request_shutdown() 関数でトリガー
  • RSHUTDOWN()
  • から
  • zend_deactivate_modules()
  • まで。
ポストリクエスト終了: PRSHUTDOWN()

このフックはほとんど使用されません。これは #RSHUTDOWN() の後に呼び出されますが、追加のエンジン コードが途中で実行されます。 特に RSHUTDOWN 後:

PHP 出力バッファーが閉じられ、そのハンドラーがフラッシュされました

PHP スーパーグローバルが破棄されました
実行エンジンはシャットダウンされました

  • このフックはめったに使用されません。 php_request_shutdown() 関数では、
  • zend_post_deactivate_modules()
  • を介して、
  • RSHUTDOWN()
  • の後にトリガーされます。
  • グローバル初期化: GINIT()

    スレッド ライブラリは、スレッドがポップアップするたびにこのフックを呼び出します。複数のプロセスを使用する場合、PHP の起動時に、MINIT() がトリガーされる前にのみこの関数が呼び出されます。

    ここではあまり詳しくは説明しませんが、単にここでグローバル変数を初期化するだけです (通常は 0 に初期化されます)。グローバル管理については、専用の章で詳しく説明します。

    グローバル変数はリクエストごとにクリーンアップされないことに注意してください。 (おそらく) 新しいリクエストごとにそれらをリセットする必要がある場合は、そのようなプロセスを RINIT() に入れる必要があります。

    グローバル スコープ管理については、専用の章で詳しく紹介されています。

    グローバル終了: GSHUTDOWN()

    スレッド ライブラリでは、スレッドが終了するたびにこのフックが呼び出されます。マルチスレッドを使用する場合、この関数は PHP の終了時 (MSHUTDOWN()) に 1 回呼び出されます。

    ここではあまり詳細を説明せずに、ここでグローバル変数を単純に初期化解除できます。通常は何もする必要はありませんが、グローバル (GINIT()) を構築している場合は、リソースが割り当てられたら、このステップでリソースを解放する必要があります。

    グローバル経営については、別章で詳しく紹介します。

    グローバル変数は各リクエスト後にクリアされないことに注意してください。つまり、GSHUTDOWN()RSHUTDOWN() の一部として呼び出されません。

    グローバル スコープ管理については、専用の章で詳しく紹介されています。

    情報収集: MINFO()

    このフックは非常に特殊で、エンジンによって自動的にトリガーされることはありません。エンジンに情報を要求した場合にのみトリガーされます。拡大。典型的な例は、phpinfo() の呼び出しです。次に、この関数が実行され、現在の拡張に関する特別な情報がストリームに出力されます。

    つまり、phpinfo() は情報を表示します。

    この関数は、php --ri pib などのリフレクション スイッチの 1 つを使用する CLI 経由、またはユーザーランド呼び出し ini_get_all() 経由で呼び出すこともできます。

    これを空白のままにすることもできます。その場合、拡張機能の名前のみが表示され、他は何も表示されません (これは MINFO() の一部であるため、INI 設定は表示されない場合があります)。

    PHP ライフサイクルについて考える

    PHP のライフサイクルを調べる

    RINIT()RSHUTDOWN() は拡張機能内で何千回もトリガーされるため、特に重要です。 PHP ステップが Web (CLI ではなく) 用であり、無制限のリクエストを処理するように構成されている場合、RINIT()/RSHUTDOWN() グループは無制限に呼び出されます。

    メモリ管理にもう一度注目していただきたいと思います。リクエストの処理中 (RINIT()RSHUTDOWN() の間) に小さなバイトがリークすることになり、フル負荷のサーバーに深刻な影響を及ぼします。このため、このような割り当てには Zend Memory Manager を使用し、メモリ レイアウトをデバッグする準備をしておくことをお勧めします。シェアードナッシング アーキテクチャの一部として、PHP は各リクエストの終了時に要求されたメモリを忘れて解放しますが、これは PHP の内部設計によるものです。

    また、クラッシュ信号が SIGSEGV (不正なメモリ アクセス) の場合、プロセス全体がクラッシュします。 PHP がマルチプロセス エンジンとしてスレッドを使用している場合、他のすべてのスレッドもクラッシュし、サーバーがクラッシュする可能性もあります。

    注意

    C 言語は PHP 言語ではありません。 C では、プログラム内のエラーによりプログラムがクラッシュして終了する可能性があります。

    関数ポインターのオーバーライドによるフック

    エンジンがコードを起動するタイミングがわかったので、エンジンにフックするために置き換えることができる注目に値する関数ポインターもあります。これらのポインターはグローバル変数であるため、MINIT() ステップに置き換えて、MSHUTDOWN() ステップに戻すことができます。

    興味深いものは次のとおりです:

    • ##AST, Zend/zend_ast.h:

        ##void (
      • zend_ast_process_t) (zend_ast ast)
      ##コンパイラ、Zend/zend_compile.h:
    • zend_op_array
        (
      • zend_compile_file )(zend_file_handle file_handle, int 型)*zend_op_array
      • (
      • zend_compile_string)(zval source_string, char filename)
      エグゼキュータ、Zend/zend_execute.h:
    • void (
        zend_execute_ex)(zend_execute_data
      • execute_data) void (
      • zend_execute_internal)(zend_execute_data
      • execute_data, zval return_value)*
      GC、Zend/zend_gc。 h:
    • ##int (

      gc_collect_cycles)(void)*
      • ##TSRM、TSRM/TSRM。h:
    • void (

      tsrm_thread_begin_func_t)(THREAD_T thread_id)*

      • void (tsrm_thread_end_func_t)(THREAD_T thread_id)*
      • エラー、Zend/zend.h:
    • void (

      zend_error_cb)(int 型、const char

      error_filename、const uint error_lineno、const char
        format、va_list args)*
      • Exceptions、Zend/zend_Exceptions.h:
        • void (zend_throw_Exception_hook)(zval ex)
    • ライフタイム、Zend/zend.h:

      • void (zend_on_timeout)(int 秒)*
      • void (zend_interrupt_function)(zend_execute_data execute_data)
      • void (zend_ticks_function)(inticks)*

    他にもありますが、上記は PHP を設計するときに最も重要です。拡張機能が必要になる場合があります。読みやすい名前ですので、詳しい説明は省略します。

    さらに詳しい情報が必要な場合は、PHP ソース コードを調べて、いつどのようにトリガーされるかを確認できます。

以上がPHP のライフサイクルを調べるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はlearnkuで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
PHPセッションの概念を簡単に説明してください。PHPセッションの概念を簡単に説明してください。Apr 26, 2025 am 12:09 AM

phpssionsStrackuserdataacrossmultiplepagerequestsusingauniqueidstoredinacookie.here'showtomanageetheemefectively:1)Startassession withsession_start()andstoredatain $ _ session.2)RegeneratesseSsessidafterloginwithsession_id(the topreventes_id)

PHPセッションに保存されているすべての値をどのようにループしますか?PHPセッションに保存されているすべての値をどのようにループしますか?Apr 26, 2025 am 12:06 AM

PHPでは、次の手順を通じてセッションデータを繰り返すことができます。1。session_start()を使用してセッションを開始します。 2。$ _Sessionアレイのすべてのキー価値ペアを介してforeachループを反復します。 3.複雑なデータ構造を処理する場合、is_array()またはis_object()関数を使用し、print_r()を使用して詳細情報を出力します。 4.トラバーサルを最適化する場合、ページングを使用して、一度に大量のデータの処理を避けることができます。これにより、実際のプロジェクトでPHPセッションデータをより効率的に管理および使用するのに役立ちます。

ユーザー認証にセッションを使用する方法を説明します。ユーザー認証にセッションを使用する方法を説明します。Apr 26, 2025 am 12:04 AM

このセッションは、サーバー側の状態管理メカニズムを介してユーザー認証を実現します。 1)セッションの作成と一意のIDの生成、2)IDはCookieを介して渡されます。3)サーバーストアとIDを介してセッションデータにアクセスします。

PHPセッションにユーザーの名前を保存する方法の例を挙げてください。PHPセッションにユーザーの名前を保存する方法の例を挙げてください。Apr 26, 2025 am 12:03 AM

tostoreauser'snameInappession、starthessession withsession_start()、thensignthenameto $ _session ['username']。1)ousession_start()toinitializethessession.2)assighttheuser'snameto $ _ session ['username']

PHPセッションを失敗させる可能性のあるいくつかの一般的な問題は何ですか?PHPセッションを失敗させる可能性のあるいくつかの一般的な問題は何ですか?Apr 25, 2025 am 12:16 AM

PHPSESSIONの障害の理由には、構成エラー、Cookieの問題、セッションの有効期限が含まれます。 1。構成エラー:正しいセッションをチェックして設定します。save_path。 2.Cookieの問題:Cookieが正しく設定されていることを確認してください。 3.セッションの有効期限:セッションを調整してください。GC_MAXLIFETIME値はセッション時間を延長します。

PHPでセッション関連の問題をどのようにデバッグしますか?PHPでセッション関連の問題をどのようにデバッグしますか?Apr 25, 2025 am 12:12 AM

PHPでセッションの問題をデバッグする方法は次のとおりです。1。セッションが正しく開始されるかどうかを確認します。 2.セッションIDの配信を確認します。 3.セッションデータのストレージと読み取りを確認します。 4.サーバーの構成を確認します。セッションIDとデータを出力し、セッションファイルのコンテンツを表示するなど、セッション関連の問題を効果的に診断して解決できます。

session_start()が複数回呼び出されるとどうなりますか?session_start()が複数回呼び出されるとどうなりますか?Apr 25, 2025 am 12:06 AM

session_start()への複数の呼び出しにより、警告メッセージと可能なデータ上書きが行われます。 1)PHPは警告を発し、セッションが開始されたことを促します。 2)セッションデータの予期しない上書きを引き起こす可能性があります。 3)session_status()を使用してセッションステータスを確認して、繰り返しの呼び出しを避けます。

PHPでセッションのライフタイムをどのように構成しますか?PHPでセッションのライフタイムをどのように構成しますか?Apr 25, 2025 am 12:05 AM

PHPでのセッションライフサイクルの構成は、session.gc_maxlifetimeとsession.cookie_lifetimeを設定することで達成できます。 1)session.gc_maxlifetimeサーバー側のセッションデータのサバイバル時間を制御します。 0に設定すると、ブラウザが閉じているとCookieが期限切れになります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール