ホームページ >バックエンド開発 >PHPチュートリアル >PHPカーネルの徹底理解(2) SAPI探索、sapi_PHPチュートリアルの徹底理解

PHPカーネルの徹底理解(2) SAPI探索、sapi_PHPチュートリアルの徹底理解

WBOY
WBOYオリジナル
2016-07-12 09:05:221003ブラウズ

PHPカーネルの徹底理解(2) - SAPI探索、sapiの徹底理解

前回の記事では、PHPカーネルの徹底理解(1)を紹介したと思います。この記事を通じて、PHP カーネルの知識についていくつかの知識を学びます。引き続きこの記事に注目してください。

SAPIはServer Application Programming Interfaceの略称です。 PHP は、アプリケーションと PHP カーネル間のデータ対話のために SAPI を介して一連のインターフェイスを提供します。

簡単に言うと、関数の入出力と同じように、Linux コマンド ラインを介して PHP コードを実行します。本質は、Linux シェルが Zend エンジンの後に一連のパラメータを渡すことです。実行するとシェルに戻り、シェルのプロセスが表示されます。同様に、PHP は Apache 経由で呼び出され、Zend エンジンの実行後にデータが Web サーバー経由で SAPI に渡され、Apache によってページに表示されます。


図 1. PHP アーキテクチャ図

PHP は、Apache、apache2filter、apache2handler、caudium、cgi、cgi-fcgi、cli、cli-server、continuity、embed、isapi、litespeed、milter、nsapi、phttpd pi3web、roxen、thttpd、tux など、さまざまな形式のインターフェイスを提供します。ウェブジェームス。ただし、一般的に使用される形式は、CLI/CGI (コマンド ライン)、Multiprocess (マルチプロセス)、Multithreaded (マルチスレッド)、FastCGI、および Embedded (組み込み) の 5 つだけです。

PHP は、現在の SAPI インターフェイス タイプを表示する関数を提供します:

コードをコピーします コードは次のとおりです:
文字列 php_sapi_name (無効)

PHP の実行と読み込み

どの SAPI が使用されるかに関係なく、PHP がスクリプトを実行する前後に、モジュールの初期化 (MINT) とシャットダウン (MSHUTDOWN)、リクエストの初期化 (RINT) とシャットダウン (RSHUTDOWN) という一連のイベントが発生します。 最初のフェーズは PHP モジュール初期化フェーズ (MINT) で、拡張内部変数の初期化、リソースの割り当て、リソース プロセッサの登録が可能です。このプロセスは、PHP インスタンスのライフ サイクル全体で 1 回だけ実行されます。

PHPモジュールとは何ですか?上記の PHP アーキテクチャ図を通じて、PHP の get_loaded_extensions 関数を使用して、コンパイルおよびロードされたすべてのモジュール/拡張機能を表示できます。これは、CLI モードの php -m と同等です。

PHP の Memcached 拡張機能のソース コードを例に挙げます:

リーリー

第 2 段階はリクエスト初期化段階 (RINT) で、モジュールが初期化されてアクティブ化された後、PHP 実行環境が作成され、すべてのモジュールによって登録された RINT 関数が呼び出されます。が呼び出され、特定の環境変数が設定され、リソースの割り当てや監査などの他のタスクが実行されます。

リーリー

3 番目の段階では、リクエストの処理が完了した後、リサイクルのために PHP_RSHUTDOWN_FUNCTION が呼び出され、最終的なクリーンアップ作業を実行する各拡張機能のリクエストを終了します。 Zend エンジンはクリーンアップ プロセス、ガベージ コレクションを実行し、以前のリクエストで使用されたすべての変数の設定を解除します。リクエストは、スクリプトを実行するか、die() または exit() 関数を呼び出すことによって完了できます

第 4 段階では、PHP ライフサイクルが終了すると、PHP_MSHUTDOWN_FUNCTION がモジュールをリサイクルします。これは、各拡張機能のモジュール シャットダウン関数であり、独自のカーネル サブシステムをシャットダウンするために使用されます。

リーリー

一般的な動作モード

5 つの一般的な SAPI モードがあります:

CLIおよびCGIモード(シングルプロセスモード)
マルチプロセスモード
マルチスレッドモード
高速CGIモード
埋め込み

1. CLI/CGI モード

CLI と CGI はどちらもシングルプロセス モードに属し、PHP のライフサイクルは 1 つのリクエストで完了します。つまり、PHP スクリプトが実行されるたびに、2 番目の部分で説明した 4 つの INT イベントと Shutdown イベントが実行されます。

図 2. CGI/CLI ライフサイクル

2. マルチプロセスモード (マルチプロセス)

マルチプロセス モードでは、PHP を Web サーバーに構築できます。PHP は、Apache でプリフォーク MPM モードと APXS モジュールにコンパイルできます。Apache が起動すると、多くの子プロセスがフォークされ、各子プロセスは独自の独立したプロセス アドレスを持ちます。空間。


図 3. マルチプロセス モードのライフサイクル

子プロセスでは、PHP のライフサイクルは、MINT を呼び出して複数のリクエスト (RINT/RSHUTDOWN) を開始および実行することです。Apache がシャットダウンされるかプロセスが終了した後、リサイクル フェーズで MSHUTDOWN が呼び出されます。

図 4. マルチプロセスのライフサイクル

マルチプロセス モデルでは、各サブプロセスはコードやデータを共有せずに独立して実行されるため、1 つのサブプロセスの終了、終了、再生成は他のサブプロセスの安定性に影響を与えません。

3. マルチスレッド

Apache2的Worker MPM采用了多线程模型,在一个进程下创建多个线程,在同一个进程地址空间执行。


图5. 多线程生命周期

4. FastCGI模式

在我们用的Nginx+PHP-FPM用的就是FastCGI模式,Fastcgi是一种特殊的CGI模式,是一种常驻进程类型的CGI,运行后可以Fork多个进程,不用花费时间动态的Fork子进程,也不需要每次请求都调用MINT/MSHUTDOWN。PHP通过PHP-FPM来管理和调度FastCGI的进程池。Nginx和PHP-FPM通过本地的TCP Socket和Unix Socket 进行通信。


图6. FastCGI模式生命周期

PHP-FPM进程管理器自身初始化,启动多个CGI解释器进程等待来自Nginx的请求。当客户端请求达到PHP-FPM,管理器选择到一个CGI进程进行处理,Nginx将CGI环境变量和标准输入发送到一个PHP-CIG子进程。PHP-CGI子进程处理完成后,将标准输出和错误信息返回给Nginx,当PHP-CGI子进程关闭连接时,请求处理完成。PHP-CGI子进程等待着下一个连接。

可以想象CGI的系统开销有多大。每一个Web 请求PHP都必须重新解析php.ini、载入全部扩展并始化全部数据结构。使用FastCGI,所有这些都只在进程启动时发生一次。另外,对于数据库和Memcache的持续连接可以工作。

5. 内嵌模式(Embedded)

Embed SAPI是一种特殊的SAPI,允许在C/C++语言中调用PHP提供的函数。这种SAPI和CLI模式一样,按照Module Init => Request Init => Request => Request Shutdown => Module Shutdown的模式运行。

Embed SAPI可以调用PHP丰富的类库,也可以实现高级玩法,比如可以查看PHP的OPCODE(PHP执行的中间码,Zend引擎的指令,由PHP代码生成)。

详细请见: http://www.bkjia.com/article/74641.htm

SAPI的运行机制

我们以CGI为例,看一下SAPI的运行机制。

static sapi_module_struct cgi_sapi_module = { 
 "cgi-fcgi",   /* 输出给php_info()使用 */ "CGI/FastCGI",   /* pretty name */ 
 php_cgi_startup,  /* startup 当SAPI初始化时,首先会调用该函数 */ 
 php_module_shutdown_wrapper, /* shutdown 关闭函数包装器,它用来释放所有的SAPI的数据结构、内存等,调用php_module_shutdown */ 
 sapi_cgi_activate,  /* activate 此函数会在每个请求开始时调用,它会做初始化,资源分配 */ 
 sapi_cgi_deactivate,  /* deactivate 此函数会在每个请求结束时调用,它用来确保所有的数据都得到释放 */ 
 sapi_cgi_ub_write,  /* unbuffered write 不缓存的写操作(unbuffered write),它是用来向SAPI外部输出数据 */ 
 sapi_cgi_flush,   /* flush 刷新输出,在CLI模式下通过使用C语言的库函数fflush实现*/ NULL,    /* get uid */ 
 sapi_cgi_getenv,  /* getenv 根据name查找环境变量 */ 
 php_error,   /* error handler 注册错误处理函数 */ 
 NULL,    /* header handler PHP调用header()时候被调用 */ 
 sapi_cgi_send_headers,  /* send headers handler 发送头部信息*/ 
 NULL,    /* send header handler 发送一个单独的头部信息 */ 
 sapi_cgi_read_post,  /* read POST data 当请求的方法是POST时,程序获取POST数据,写入$_POST数组 */ 
 sapi_cgi_read_cookies,  /* read Cookies 获取Cookie值 */ 
 sapi_cgi_register_variables, /* register server variables 给$_SERVER添加环境变量 */ 
 sapi_cgi_log_message,  /* Log message 输出错误信息 */ 
 NULL,    /* Get request time */ 
 NULL,    /* Child terminate */ 
 STANDARD_SAPI_MODULE_PROPERTIES 
}; 

由上面代码可见,PHP的SAPI像是面向对象中基类,SAPI.h和SAPI.c包含的函数是抽象基类的声明和定义,各个服务器用的SAPI模式,则是继承了这个基类,并重新定义基类方法的子类。

总结

PHP的SAPI是Zend引擎提供的一组标准交互接口,通过注册初始化、析构、输入、输出等接口,我们可以将应用程序运行在Zend引擎上,也可以把PHP嵌入到类似Apache的Web Server中。PHP常见的SAPI模式有五种,CGI/CLI模式、多进程模式、多线程模式、FastCGI模式和内嵌模式。

了解PHP的SAPI机制意义重大,帮助我们理解PHP的生命周期,并了解如何更好的通过C/C++为PHP编写扩展,并在生命周期中找到提高系统性能的方式。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/1069345.htmlTechArticle深入理解PHP内核(二)之SAPI探究,深入理解sapi 在上篇文章给大家介绍了深入了解PHP内核(一),相信大家通过本文多多少少都学到些知识吧...
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。