ホームページ  >  記事  >  バックエンド開発  >  PHP の下部にある PHP ライフサイクルの詳細な説明

PHP の下部にある PHP ライフサイクルの詳細な説明

小云云
小云云オリジナル
2018-03-22 15:36:071878ブラウズ

この記事では、主に PHP の下部にある PHP ライフサイクルの詳細な説明を共有します。お役に立てれば幸いです。

1. PHP 動作モード:

PHP の 2 つの動作モードは、WEB モードと CLI モードです。 どのモードでも、PHP は同じように動作し、SAPI として実行されます。

1. ターミナルに php コマンドを入力すると、CLI が使用されます。

PHP がリクエストを完了するのをサポートする Web サーバーのようなものです。リクエストが完了すると、制御がターミナルに戻ります。

2. Apache または他の Web サーバーをホストとして使用している場合、リクエストが来ると、PHP はリクエストの完了をサポートします。一般的には以下のものがあります:

マルチプロセス (通常、PHP リクエストを処理するために Apache モジュールとしてコンパイルされます)

マルチスレッドモード

2. すべての始まり: SAPI インターフェース

通常、私たちはApache や Nginx などの Web サーバーを介して php Web プログラムのテスト スクリプトを作成するか、コマンド ラインで php プログラムを介して PHP スクリプトを実行します。スクリプトが実行された後、サーバーが応答し、ブラウザーに応答情報が表示されます。 、標準出力 表示内容。 PHP インタープリターがどこにあるかを気にすることはほとんどありません。Web サーバー経由でのスクリプトの実行とコマンド ライン プログラムの実行は大きく異なりますが、実際には、コマンド ライン プログラムの動作は Web プログラムに似ており、コマンド ライン パラメーターが に渡されます。スクリプトの実行は、URL を介して PHP ページをリクエストするのと同じです。スクリプトの完了後、応答結果が返されますが、スクリプトの実行の開始は SAPI を介して実行されます。インターフェイス

1) apache を起動します: /usr/local/apache/bin/apachectl の起動に応じて、特定の SAPI が起動すると、PHP はカーネル サブシステムを初期化して起動します。スタートアップ ルーチンの終わり近くで、各拡張機能のコードがロードされ、そのモジュール初期化ルーチン (MINIT) が呼び出されます。これにより、各拡張機能は内部変数の初期化、リソースの割り当て、リソース ハンドラーの登録、および独自の関数の ZE への登録が可能になり、スクリプトが関数を呼び出すときにどのコードを実行するかを ZE が認識できるようになります。

2) リクエスト処理の初期化 : 次に、PHP は、SAPI レイヤーがページの処理をリクエストするのを待ちます。 CGI や CLI などの SAPI の場合、これはただちに 1 回だけ発生します。 Apache、IIS、またはその他の成熟した Web サーバー SAPI の場合、これはリモート ユーザーがページをリクエストするたびに発生するため、何度も (場合によっては同時に) 繰り返されることになります。リクエストの生成方法に関係なく、PHP はまず ZE にスクリプトの実行環境をセットアップするよう依頼し、次に各拡張機能のリクエストの初期化を呼び出します。 (RINIT) 機能。 RINIT は、拡張機能に特定の環境変数を設定したり、要求に応じてリソースを割り当てたり、監査などの他のタスクを実行したりする機会を与えます。セッション拡張における RINIT の役割の典型的な例は、session.auto_start オプションが有効になっている場合、RINIT がユーザー空間の session_start() 関数と事前にアセンブルされた $_SESSION 変数を自動的にトリガーすることです。

3) PHP コードを実行します: リクエストが初期化されると、ZE が制御を引き継ぎ始め、PHP スクリプトをシンボルに変換し、最後にオペコードを形成して段階的に実行します。オペコードが拡張関数を呼び出す必要がある場合、ZE はパラメーターを関数にバインドし、関数が完了するまで一時的に制御を放棄します。

4) スクリプトの終了: スクリプトの実行後、PHP は各拡張機能のリクエスト シャットダウン (RSHUTDOWN) 関数を呼び出して、最終的なクリーンアップ作業 (セッション変数のディスクへの保存など) を実行します。次に、ZE はクリーンアップ プロセス (ガベージ コレクション) を実行し、前のリクエストで使用されたすべての変数を効果的に unset() します。

5)、sapi close: 完了すると、PHP は SAPI からの他のドキュメント要求またはシャットダウン信号を待ち続けます。 CGI や CLI などの SAPI の場合、「次のリクエスト」がないため、SAPI はすぐにシャットダウンを開始します。シャットダウン中、PHP は各拡張機能を再度繰り返し、モジュール シャットダウン (MSHUTDOWN) 関数を呼び出し、最終的に独自のカーネル サブシステムをシャットダウンします。

簡単なプロセスは次のとおりです:

1. PHP は Apache の起動とともに実行されます。
2. PHP は mod_php5.so モジュール (具体的には SAPI、つまりサーバー アプリケーション プログラミング) を介して Apache に接続されます。インターフェース);
3. PHP には、カーネル、Zend エンジン、拡張層の合計 3 つのモジュールがあります。
4. PHP カーネルは、リクエスト、ファイル ストリーム、エラー処理、およびその他の関連操作を処理するために使用されます。 ) は、ソース ファイルをマシン語に変換し、仮想マシン上で実行するために使用されます。
6. 拡張レイヤーは、PHP が特定の操作を実行するために使用する関数、クラス ライブラリ、およびストリームのセットです。たとえば、MySQL データベースに接続するには、mysql 拡張機能が必要です。
7. ZE がプログラムを実行するとき、いくつかの拡張機能に接続する必要がある場合があります。このとき、ZE は制御を拡張機能に渡し、処理後にそれを返します。特定のタスク;
8. 最後に、ZE はプログラムの実行結果を PHP カーネルに返し、PHP カーネルはその結果を SAPI 層に送信し、最終的にブラウザに出力します。

3. PHP の開始フェーズと終了フェーズ

開始フェーズには 2 つのプロセスがあります:

最初のプロセス: リクエストが到着する前に発生する Apache 起動のプロセス。これは、SAPI ライフ サイクル全体の開始フェーズ (MINIT) です (Apache の開始後のライフ サイクル全体、またはコマンド ライン プログラムの実行プロセス全体など)。このフェーズは 1 回だけ実行されます。。 Apache の起動後、PHP インタープリタも起動し、PHP は各拡張機能 (モジュール) の MINIT メソッドを呼び出し、これらの拡張機能を使用可能な状態に切り替えます。 php.ini ファイルでどのような拡張子が開かれているかを確認してください。 MINIT は「モジュールの初期化」を意味します。各モジュールは、他のリクエストを処理するための一連の関数、クラス ライブラリなどを定義します。 モジュールは、定数の登録、モジュールで使用されるクラスの定義など、この段階でいくつかの初期化作業を実行できます。 典型的な モジュール コールバック関数 MINIT メソッドは次のとおりです:

PHP_MINIT_FUNCTION(myphpextension) { /* Initialize functions, classes etc */ }
{
    // 注册常量或者类等初始化操作
    return SUCCESS; 
}

2 番目のプロセスはリクエストフェーズで発生しますページリクエストが発生すると、各リクエストの前に初期化プロセスが実行されます (RINIT リクエストが開始されます)

リクエストが到着した後、

SAPI レイヤーが制御を引き継ぎます。 PHP 層に渡って、PHP の初期化このリクエストスクリプトの実行に必要な環境変数 を要求します。これには、PHP の実行中に変数名と変数値の内容を保存するシンボル テーブルなどの実行環境の作成などが含まれます。 たとえば、セッション モジュールの RINIT が php.ini で有効になっている場合、モジュールの RINIT が初期化されるときに $_SESSION 変数が初期化されます。が呼び出され、関連するコンテンツが読み込まれます。 次に、PHP はすべてのモジュールの RINIT 関数を呼び出します。これは、「初期化の要求」です。 この段階では、各モジュールはいくつかの関連操作も実行できます。 モジュールの RINIT 関数は MINIT 関数に似ています。RINIT メソッドはプログラムの実行の間に自動的に開始される準備プロセスとみなすことができます。

PHP_RINIT_FUNCTION(myphpextension)
{
    // 例如记录请求开始时间
    // 随后在请求结束的时候记录结束时间.这样我们就能够记录下处理请求所花费的时间了
    return SUCCESS; 
}

終了フェーズは 2 つの段階に分かれています:

リクエストが処理された後、スクリプトは最後まで実行されるか、exit() を呼び出すことによって終了フェーズに入ります。または die() 関数、PHP の両方 開始フェーズに対応して終了フェーズに入ります。終了フェーズも 2 つのステージに分かれています。1 つはリクエストの終了後 (RSHUWDOWN)、もう 1 つは SAPI ライフの終了時です。サイクル (MSHUTDOWN)。

最初の各リンク: リクエストが処理された後の終了フェーズ: リクエストが処理された後、終了フェーズに入り、PHP はクリーンアップを開始します。プロセス。各モジュールの RSHUTDOWN メソッドを順番に呼び出します。 RSHUTDOWN は、プログラムの実行中に生成されたシンボル テーブルをクリアする、つまり各変数の unset 関数を呼び出すために使用されます。典型的な RSHUTDOWN メソッドは次のとおりです:

PHP_RSHUTDOWN_FUNCTION(myphpextension)
{
    // 例如记录请求结束时间, 并把相应的信息写入到日至文件中.
    return SUCCESS; 
}

2 番目のリンク:

最後に、すべてのリクエストが処理され、PHP は各拡張機能の MSHUTDOWN メソッドを呼び出す準備が整います。各モジュールのメモリを解放する機会。 (

これです CGIやCLIなどのSAPIの場合、「次のリクエスト」がないため、SAPIはすぐにクローズを開始します)代表的なRSHUTDOWNメソッドは以下の通りです:

PHP_MSHUTDOWN_FUNCTION(extension_name) { 
    /* Free handlers and persistent memory etc */ 
    return SUCCESS; 
}
このようにして、PHP全体のライフサイクルが終了します。なお、「第1ステップの開始」と「第2ステップの終了」はサーバからのリクエストがない場合のみ実行されます。

SAPI は次の段階で PHP を実行します:
1. モジュール初期化フェーズ (モジュール初期化) :
つまり、各拡張ソース コードの PHP_MINIT_FUNCTION 内のメソッドを呼び出してモジュールを初期化し、モジュールに必要ないくつかの変数を変更します。アプリケーション、メモリ割り当てなど初 2.
Request Init :
クライアントのリクエストを受信後、PHP_RINIT_FUNCTION の各拡張メソッドを呼び出し、PHP スクリプトの実行環境を初期化します。
3. PHP スクリプトを実行
4. Request Shutdown (リクエストシャットダウン) :
3. このとき、各拡張機能の PHP_RSHUTDOWN_FUNCTION メソッドが呼び出され、リクエストサイトをクリーンアップし、ZE が変数とメモリをリサイクルします。模 5.
モジュールの SHUTDOWN : Web サーバーの終了またはコマンド ライン スクリプトの実行は、ソース コード内の php_mshutdown_function メソッドを呼び出します。これは、単一プロセス SAPI モードに属します。このタイプのリクエストは、リクエストを一度処理した後に閉じられます。つまり、次のリンクのみを経由します。 開始 - リクエストの開始 - リクエストのクローズ - 終了 SAPI インターフェイスの実装はライフ サイクルを完了します。図に示すように:

、 5、マルチプロセス SAPI ライフサイクル

通常、PHP は通常、PHP リクエストを処理するために Apache としてコンパイルされたモジュールです。 Apache は通常、マルチプロセス モードを採用しており、Apache が起動されると、各プロセスは独立したメモリ領域を持ちます。ただし、各プロセスの開始ステージと終了ステージが実行されます。プロセスは生成後にフォークされ、プロセスのライフサイクル全体を通じて複数のリクエストが処理される可能性があります。 Apache がシャットダウンまたはプロセスされている場合のみ

被结束之后才会进行关闭阶段,在这两个阶段之间会随着每个请求重复请求开始-请求关闭的环节。 

如图所示:

                                     


6、多线程的SAPI生命周期

多线程模式和多进程中的某个进程类似,不同的是在整个进程的生命周期内会并行的重复着 请求开始-请求关闭的环节.

在这种模式下,只有一个服务器进程在运行着,但会同时运行很多线程,这样可以减少一些资源开销,向Module init和Module shutdown就只需要运行一遍就行了,一些全局变量也只需要初始化一次,因为线程独具的特质,使得各个请求之间方便的共享一些数据成为可能。

 多线程工作方式如下图

                              

7、Apache一般使用多进程模式prefork

        在linux下使用#http –l 命令可以查看当前使用的工作模式。也可以使用#apachectl -l命令。
        看到的prefork.c,说明使用的prefork工作模式。

        prefork 进程池模型,用在 UNIX 和类似的系统上比较多,主要是由于写起来方便,也容易移植,还不容易出问题。要知道,如果采用线程模型的话,用户线程、内核线程和混合型线程有不同的特性,移植起来就麻烦。prefork 模型,即预先 fork() 出来一些子进程缓冲一下,用一个锁来控制同步,连接到来了就放行一个子进程,让它去处理。

    prefork MPM 使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:他能够使用那些没有处理好线程安全的第三方模块,并 且对于那些线程调试困难的平台而言,他也更容易调试一些。

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

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。