検索
ホームページバックエンド開発PHPチュートリアルPHPインタープリタエンジン実行処理

カタログ

1. SAPI接口2. PHP CLI模式解释执行脚本流程3. PHP Zend Complile/Execute函数接口化(Hook Call架构基础)

1. SAPI インターフェイス

PHP の SAPI 層は、上位層インターフェイスのカプセル化を実装しているため、PHP を多くのモード シナリオ (Apache、ningx、cgi、fastcgi、cli など) で使用できます。 to cli SAPI では、PHP インタプリタ エンジンが PHP ユーザー モード ソース コード ファイルを処理する方法を学習します。Cli (コマンド ライン インターフェイス) は、PHP をサーバーにインストールした後、デフォルトでインストールされます。 , 通常、実行可能ファイルを生成します

スクリプト実行の開始は、SAPI インターフェイスの実装から始まります。たとえば、Apache の mod_php SAPI 実装は、Apache から取得した一部の情報を初期化し、その内容を出力コンテンツで Apache に返す必要があるというだけです。

0x1: sapi_module_struct。

SAPI を定義するには、まず sapi_module_structPHP-SRC/sapi/cli/php_cli.c を定義します。

/* {{{ sapi_module_struct cli_sapi_module */static sapi_module_struct cli_sapi_module = {    "cli",                            /* name php_info()的时候被使用 */    "Command Line Interface",        /* pretty name */    php_cli_startup,                /* startup */    php_module_shutdown_wrapper,    /* shutdown */    NULL,                            /* activate */    sapi_cli_deactivate,            /* deactivate */    sapi_cli_ub_write,                /* unbuffered write */    sapi_cli_flush,                    /* flush */    NULL,                            /* get uid */    NULL,                            /* getenv */    php_error,                        /* error handler */    sapi_cli_header_handler,        /* header handler */    sapi_cli_send_headers,            /* send headers handler */    sapi_cli_send_header,            /* send header handler */    NULL,                            /* read POST data */    sapi_cli_read_cookies,          /* read Cookies */    sapi_cli_register_variables,    /* register server variables */    sapi_cli_log_message,            /* Log message */    NULL,                            /* Get request time */    NULL,                            /* Child terminate */        STANDARD_SAPI_MODULE_PROPERTIES};/* }}} */

この構造には、php_info() を呼び出すときに使用される名前などのいくつかの定数が含まれています。一部の初期化関数、終了関数、および一部の関数ポインターは、Zend にデータの取得および出力方法を指示するために使用されます。以下のプロセスの紹介で 1 つずつ説明します

関連リンク:

PHP CLI モードの説明

2.スクリプトプロセス

0x1: プロセスの起動

メインプロセス main が必要な初期化作業を実行した後、SAPI 論理プロセスに入り、いくつかの環境変数を初期化します。これは SAPI ライフサイクル全体を通して有効になります

0x2: MIT

http://www.nowamagic.net/librarys/veda/detail/1285

MINIT は「モジュールの初期化」を意味します。各モジュールは、他のリクエストを処理するための一連の関数、クラス ライブラリなどを定義します。典型的な MINIT メソッドは次のとおりです。

int main(int argc, char *argv[]){    ..    sapi_module_struct *sapi_module = &cli_sapi_module;    ..    sapi_module->ini_defaults = sapi_cli_ini_defaults;    sapi_module->php_ini_path_override = ini_path_override;    sapi_module->phpinfo_as_text = 1;    sapi_module->php_ini_ignore_cwd = 1;    sapi_startup(sapi_module);    sapi_started = 1;    ..

0x3: RINIT

ページ リクエストが発生すると、SAPI 層は PHP 層に制御を渡します。 。したがって、PHP は、このリクエストに応答するために必要な環境変数を設定します。同時に、実行中に生成された変数名と値を保存する変数テーブルも作成します。 PHP は各モジュールの RINIT メソッド、つまり「初期化の要求」を呼び出します

典型的な例は、セッション モジュールの RINIT です。セッション モジュールが php.ini で有効になっている場合、RINIT の実行時に $_SESSION 変数が初期化されます。モジュールの が呼び出され、関連する内容が

に読み込まれます

RINIT メソッドは、プログラムが実行される前に自動的に開始される準備プロセスとみなすことができます。典型的な RINIT メソッドは次のとおりです

static int php_cli_startup(sapi_module_struct *sapi_module) /* {{{ */{    if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {        return FAILURE;    }    return SUCCESS;}

PHP は、リクエストごとにいくつかの初期化およびリソース割り当てトランザクションを処理します。この部分は、activate フィールドが定義される部分です。上記の構造体から、CGI の場合、上記の cli に対応する cli_sapi_module 構造体が初期化処理ハンドルを提供していないことがわかります。 mod_php の場合は異なります。Apache プールにリソース デストラクターを登録し、スペースを適用し、環境変数を初期化する必要があります。

0x4: SCRIPT

PHP は、php_execute_script(&file_handle TSRMLS_CC) スクリプト php-5.6 を通じて PHP を実行します。 17mainmain.c

/* {{{ php_module_startup */int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules){    ..    zend_module_entry *module;    ..    module_shutdown = 0;    module_startup = 1;    sapi_initialize_empty_request(TSRMLS_C);    sapi_activate(TSRMLS_C);    ..    /* start additional PHP extensions */    php_register_extensions_bc(additional_modules, num_additional_modules TSRMLS_CC);    /* load and startup extensions compiled as shared objects (aka DLLs)       as requested by php.ini entries       theese are loaded after initialization of internal extensions       as extensions *might* rely on things from ext/standard       which is always an internal extension and to be initialized       ahead of all other internals     */    php_ini_register_extensions(TSRMLS_C);    zend_startup_modules(TSRMLS_C);    /* start Zend extensions */    zend_startup_extensions();    ..

php_execute_script は最終的に zend_execute_scripts{PHPSRC}/Zend/zend.c

PHP_MINIT_FUNCTION(extension_name){ /* Initialize functions, classes etc */ }
1. コンパイル コンパイル プロセス

zend_compile_file は関数ポインタであり、/ 内の {PHPSRC}/Zend

PHP_RINIT_FUNCTION(extension_name) { /* Initialize session variables,pre-populate variables, redefine global variables etc */ }

で宣言されます。 zend_compile.c

エンジンが初期化されると、compile_file 関数のアドレスが zend_compile_file に割り当てられます。 1)

zend_execute は関数ポインター (コンパイル プロセスを使用して取得されるオペコード配列) でもあり、これは {PHPSRC}/Zend/zend_execute.c で宣言されます

/* {{{ php_execute_script */PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC){    //file_handle的类型为zend_file_handle,这个是zend对文件句柄的一个封装,里面的内容和待执行脚本相关    zend_file_handle *prepend_file_p, *append_file_p;    zend_file_handle prepend_file = {0}, append_file = {0};    ..    //php_execute_script最终是调用的zend_execute_scripts    retval = (zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);    ..

エンジンが初期化されると、実行関数のアドレスがzend_execute に割り当てられ、実行 {PHPSRC}/Zend/zend_vm_execute.h で定義されます

//此函数具有可变参数,可以一次执行多个PHP文件ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */{    ..    EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);    ..    if (EG(active_op_array))     {        EG(return_value_ptr_ptr) = retval ? retval : NULL;        zend_execute(EG(active_op_array) TSRMLS_CC);        ..

0x5: RSHUTDOWN

ページが実行されると (ファイルの最後に到達するか、exit または die 関数で中止されるかに関係なく)、 PHP がクリーンアップ プログラムを開始します。各モジュールの RSHUTDOWN メソッドを順番に呼び出します。 RSHUTDOWN は、プログラムの実行時に生成されたシンボル テーブルをクリアするために使用されます。つまり、各変数の unset 関数を呼び出します

ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);  

0x6: MSHUTDOWN

最後に、すべてのリクエストが処理され、SAPI を閉じる準備ができ、PHP が実行されます。 2 番目のステップの実行を開始します: PHP は各拡張機能の MSHUTDOWN メソッドを呼び出します。これが各モジュールがメモリを解放する最後のチャンスです

//函数以zend_file_handle指针作为参数,返回一个指向zend_op_array的指针ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC){    ..    //Lex词法解析过程    ..

/main/main.c

ZEND_API extern void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);  

関連リンク:

//zend_execute以一个指向zend_op_array结构的指针作为参数,这个指针即前面zend_compile_file的返回值,zend_execute就开始执行op_array中的op code,在执行op code的过程中,就实现了PHP语言的各种功能ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC){    if (EG(exception)) {        return;    }     zend_execute_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);}

3.関数インターフェイスの実行 (フックコールアーキテクチャの基本)

PHP内核在设计架构实现的时候,除了提供了扩展机制,还在Zend的两个关键流程(compile、execute)提供了Hook机制,PHP扩展开发人员可以Hook劫持Zend的编译/解释执行流程,在Zend编译执行之前先执行自定义的代码逻辑,然后再交还控制权给Zend。在引擎初始化(zend_startup)的时候

1. end_execute指向了默认的execute2. zend_compile_file指向了默认的compile_file

我们可以在实际编译和执行之前(RINIT阶段中)将zend_execute和zend_compile_file重写为其他的编译和执行函数,这样就为我们扩展引擎留下了钩子,比如一个比较有名的查看PHP的op code的扩展vld,此扩展就是在每次请求初始化的钩子函数(PHP_RINIT_FUNCTION)中,将zend_execute和zend_compile_file替换成自己的vld_execute和vld_compile_file,这两个函数其实是对原始函数进行了封装,添加了输出opcode信息的附加功能,因为引擎初始化是发生在模块请求初始化之前,而模块请求初始化又是在编译和执行之前,所以这样的覆盖能达到目的

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHPロギング:PHPログ分析のベストプラクティスPHPロギング:PHPログ分析のベストプラクティスMar 10, 2025 pm 02:32 PM

PHPロギングは、Webアプリケーションの監視とデバッグ、および重要なイベント、エラー、ランタイムの動作をキャプチャするために不可欠です。システムのパフォーマンスに関する貴重な洞察を提供し、問題の特定に役立ち、より速いトラブルシューティングをサポートします

Laravelでフラッシュセッションデータを使用しますLaravelでフラッシュセッションデータを使用しますMar 12, 2025 pm 05:08 PM

Laravelは、直感的なフラッシュメソッドを使用して、一時的なセッションデータの処理を簡素化します。これは、アプリケーション内に簡単なメッセージ、アラート、または通知を表示するのに最適です。 データは、デフォルトで次の要求のためにのみ持続します。 $リクエスト -

PHPのカール:REST APIでPHPカール拡張機能を使用する方法PHPのカール:REST APIでPHPカール拡張機能を使用する方法Mar 14, 2025 am 11:42 AM

PHPクライアントURL(CURL)拡張機能は、開発者にとって強力なツールであり、リモートサーバーやREST APIとのシームレスな対話を可能にします。尊敬されるマルチプロトコルファイル転送ライブラリであるLibcurlを活用することにより、PHP Curlは効率的なexecuを促進します

Laravelテストでの簡略化されたHTTP応答のモッキングLaravelテストでの簡略化されたHTTP応答のモッキングMar 12, 2025 pm 05:09 PM

Laravelは簡潔なHTTP応答シミュレーション構文を提供し、HTTP相互作用テストを簡素化します。このアプローチは、テストシミュレーションをより直感的にしながら、コード冗長性を大幅に削減します。 基本的な実装は、さまざまな応答タイプのショートカットを提供します。 Illuminate \ support \ facades \ httpを使用します。 http :: fake([[ 'google.com' => 'hello world'、 'github.com' => ['foo' => 'bar']、 'forge.laravel.com' =>

Codecanyonで12の最高のPHPチャットスクリプトCodecanyonで12の最高のPHPチャットスクリプトMar 13, 2025 pm 12:08 PM

顧客の最も差し迫った問題にリアルタイムでインスタントソリューションを提供したいですか? ライブチャットを使用すると、顧客とのリアルタイムな会話を行い、すぐに問題を解決できます。それはあなたがあなたのカスタムにより速いサービスを提供することを可能にします

PHPにおける後期静的結合の概念を説明します。PHPにおける後期静的結合の概念を説明します。Mar 21, 2025 pm 01:33 PM

記事では、PHP 5.3で導入されたPHPの後期静的結合(LSB)について説明し、より柔軟な継承を求める静的メソッドコールのランタイム解像度を可能にします。 LSBの実用的なアプリケーションと潜在的なパフォーマ

フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。フレームワークのカスタマイズ/拡張:カスタム機能を追加する方法。Mar 28, 2025 pm 05:12 PM

この記事では、フレームワークにカスタム機能を追加し、アーキテクチャの理解、拡張ポイントの識別、統合とデバッグのベストプラクティスに焦点を当てています。

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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境