PHP ライフサイクルの各段階で、いくつかのサービス関連の操作が SAPI インターフェイスを通じて実装されます。 これらの組み込み実装の物理的な場所は、PHP ソース コードの SAPI ディレクトリ内にあります。このディレクトリには、コマンド ライン プログラムの実装、Apache の mod_php モジュールの実装、fastcgi の実装など、各サーバー抽象化レイヤーの PHP コードが保存されます。
各サーバー抽象化レイヤー間では同じ規則に従います。ここではこれを SAPI インターフェイスと呼びます。 各 SAPI 実装は、_sapi_module_struct 構造体変数です。 (SAPI インターフェース)。 PHP ソース コードでは、サーバー関連の情報を呼び出す必要がある場合、すべて SAPI インターフェイスの対応するメソッドを呼び出すことによって実装され、各サーバー抽象化レイヤーの実装時に対応するメソッドは独自の実装を持ちます。
以下は、SAPI の簡単な図です:
cgi モードと apache2 サーバーを例として、それらの起動方法は次のとおりです:
<code>cgi_sapi_module.startup(&cgi_sapi_module) // cgi模式 cgi/cgi_main.c文件 apache2_sapi_module.startup(&apache2_sapi_module); // apache2服务器 apache2handler/sapi_apache2.c文件 </code>
ここでの cgi_sapi_module は、sapi_module_struct 構造体の静的変数です。 その起動メソッドは php_cgi_startup 関数ポインタを指します。この構造体には、スタートアップ関数ポインターに加えて、他の多くのメソッドまたはフィールドがあります。 その定義の一部は次のとおりです:
<code>struct _sapi_module_struct { char *name; // 名字(标识用) char *pretty_name; // 更好理解的名字(自己翻译的) int (*startup)(struct _sapi_module_struct *sapi_module); // 启动函数 int (*shutdown)(struct _sapi_module_struct *sapi_module); // 关闭方法 int (*activate)(TSRMLS_D); // 激活 int (*deactivate)(TSRMLS_D); // 停用 int (*ub_write)(const char *str, unsigned int str_length TSRMLS_DC); // 不缓存的写操作(unbuffered write) void (*flush)(void *server_context); // flush struct stat *(*get_stat)(TSRMLS_D); // get uid char *(*getenv)(char *name, size_t name_len TSRMLS_DC); // getenv void (*sapi_error)(int type, const char *error_msg, ...); /* error handler */ int (*header_handler)(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers TSRMLS_DC); /* header handler */ /* send headers handler */ int (*send_headers)(sapi_headers_struct *sapi_headers TSRMLS_DC); void (*send_header)(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC); /* send header handler */ int (*read_post)(char *buffer, uint count_bytes TSRMLS_DC); /* read POST data */ char *(*read_cookies)(TSRMLS_D); /* read Cookies */ /* register server variables */ void (*register_server_variables)(zval *track_vars_array TSRMLS_DC); void (*log_message)(char *message); /* Log message */ time_t (*get_request_time)(TSRMLS_D); /* Request Time */ void (*terminate_process)(TSRMLS_D); /* Child Terminate */ char *php_ini_path_override; // 覆盖的ini路径 ... ... }; </code>
上記の構造は、各サーバーのインターフェイス実装で定義されます。 Apache2 で定義されているとおり:
<code>static sapi_module_struct apache2_sapi_module = { "apache2handler", "Apache 2.0 Handler", php_apache2_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ ... } </code>
PHP に組み込まれている SAPI 実装の多くは、保守されなくなっているか、やや非主流になっています。現在、PHP コミュニティは、一部の SAPI をコード ベースから移動することを検討しています。 コミュニティは、本当に必要な場合、または一部の機能がほぼ普遍的な場合を除き、多くの機能が PECL ライブラリに含まれると考えています。たとえば、非常に人気のある APC キャッシュ拡張機能はコア コード ベースに組み込まれます。
SAPI 全体は、オブジェクト指向のテンプレート メソッド パターンの適用に似ています。 SAPI.c および SAPI.h ファイルに含まれる一部の関数は、テンプレート メソッド パターンの抽象テンプレートであり、各サーバーの定義および sapi_module の関連実装は特定のテンプレートです。
このような構造は、PHP ソース コードの多くの場所で使用されます。たとえば、PHP 拡張機能の開発では、各拡張機能で zend_module_entry 構造体を定義する必要があります。 この構造体の機能は、テンプレート メソッド パターンに似たアプリケーションである sapi_module_struct 構造体に似ています。 PHP のライフサイクルでは、拡張機能を呼び出す必要がある場合、呼び出されるメソッドは zend_module_entry 構造体で指定されたメソッドです。前のセクションで説明したように、各拡張機能のリクエストの初期化を実行するときは、 request_startup_func メソッドが一律に呼び出されます。 、各拡張機能の定義では、request_startup_func に対応する関数がマクロ PHP_RINIT によって指定されます。 VLD 拡張機能を例に挙げます。そのリクエストは PHP_RINIT(vld) として初期化され、それに応じて拡張機能には次の関数の実装が必要です:
<code>PHP_RINIT_FUNCTION(vld) { } </code>
したがって、同様に、実装する場合は、各サーバー インターフェイスも対応する SAPI を実装する必要があります。
').addClass('事前番号付け').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });以上、API と sap の内容を含めて 07-Discuss SAPI を再度紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。