PHP カーネル解析 (7) - 拡張機能
要約: ここで読み取られるphpのバージョンはPHP-7.1.0 RC3で、コードを読み取るためのプラットフォームはlinuxです。この反省の拡張を勉強してみましょう。リフレクション拡張ディレクトリは ext/reflection に存在します。実際、内部のコードは非常に単純です。 1 つの .h ファイルと 1 つの .c ファイル。まず .c ファイルを見てみましょう。多くのことがわかります...
ここで読み取られる php のバージョンは PHP-7.1.0 RC3、コードを読み取るためのプラットフォームは Linux です。
リフレクション拡張機能を勉強しましょう。
リフレクション拡張ディレクトリは ext/reflection に存在します。実際、内部のコードは非常に単純です。 1 つの .h ファイルと 1 つの .c ファイル。
まず .c ファイルを見てみましょう。ZEND_METHOD に対応するマクロがたくさんあることがわかります
1 ZEND_METHOD(reflection_function, getReturnType) 2 { 3 ... 4 }
:
1 #define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name)) 2 #define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS) 3 #define ZEND_MN(name) zim_##name 4 #define INTERNAL_FUNCTION_PARAMETERS zend_execute_data *execute_data, zval *return_value
ここの ## は接続を表し、展開は実際には次のことを意味します:
void zim_reflection_function_getReturnType(zend_execute_data *execute_data, zval *return_value)
、ここでは ZEND_METHOD を使用しています。関数 zim_reflection_function_getReturnType が定義されていますが、実行コードからここでどのように呼び出されるのでしょうか。
わかりました。ここでは拡張呼び出しスタックは表示されません。次に、gdb を使用してコールスタックを見てみましょう。
リフレクション拡張を使用するスクリプトを作成します:
1 <?php 2 3 class B 4 { 5 public function test(): B 6 { 7 8 } 9 } 10 11 function getB(): B 12 { 13 14 } 15 16 $rc = new ReflectionMethod('B', 'test'); 17 var_dump((string)$rc->getReturnType(), $rc->getReturnType()); 18 19 $rc = new ReflectionFunction('getB'); 20 var_dump((string)$rc->getReturnType(), $rc->getReturnType());
管理には gdb を使用します。拡張コードの中に関数reflection_type_factoryがあるので、これを管理に使用します。
01 (gdb) b reflection_type_factory 02 03 (gdb) run -f /home/xiaoju/software/php7/demo/echo.php 04 05 (gdb) s 06 07 (gdb) bt 08 #0 reflection_type_factory (fptr=0x7ffff6004210, closure_object=0x0, arg_info=0x7ffff6079048, 09 object=0x7ffff60140d0) at /home/xiaoju/webroot/php-src/php-src-master/ext/reflection/php_reflection.c:1280 10 #1 0x0000000000760d23 in ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER (execute_data=0x7ffff6014030) 11 at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:1097 12 #2 0x000000000073fc88 in execute_ex (ex=<value optimized="" out="">) 13 at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:432 14 #3 0x000000000078b670 in zend_execute (op_array=0x7ffff60782a0, return_value=<value optimized="" out="">) 15 at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend_vm_execute.h:474 16 #4 0x00000000006e48a3 in zend_execute_scripts (type=8, retval=0x0, file_count=3) 17 at /home/xiaoju/webroot/php-src/php-src-master/Zend/zend.c:1464 18 #5 0x0000000000684870 in php_execute_script (primary_file=0x7fffffffe090) 19 at /home/xiaoju/webroot/php-src/php-src-master/main/main.c:2541 20 #6 0x000000000078e9ea in do_cli (argc=3, argv=0xee1bc0) 21 at /home/xiaoju/webroot/php-src/php-src-master/sapi/cli/php_cli.c:994 22 #7 0x000000000078f1ea in main (argc=3, argv=0xee1bc0) 23 at /home/xiaoju/webroot/php-src/php-src-master/sapi/cli/php_cli.c:1387 24 (gdb)</value></value>
OK、このコンテキストは非常に明確に見ることができます:
main->do_cli->php_execute_scripts->zend_execute->execute_ex->ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER->reflection_type_factory
main、do_cli、php_execute_scripts、zend_execute、execute_ex については、前の main 関数の分析に基づいて、各関数の役割を簡単に理解できます。言い換えれば、execute_ex は実際にオペコードを呼び出す最も重要な関数です。
このスクリプトのオペコードを比較してください:
01 L1-21 {main}() /home/xiaoju/software/php7/demo/echo.php - 0x7fd6a127f000 + 30 ops 02 L3 #0 NOP 03 L11 #1 NOP 04 L16 #2 NEW "ReflectionMethod" @1 05 L16 #3 SEND_VAL_EX "B" 1 06 L16 #4 SEND_VAL_EX "test" 2 07 L16 #5 DO_FCALL 08 L16 #6 ASSIGN $rc @1 09 L17 #7 INIT_FCALL 112 "var_dump" 10 L17 #8 INIT_METHOD_CALL $rc "getReturnType" 11 L17 #9 DO_FCALL @4 12 L17 #10 CAST @4 ~5 13 L17 #11 SEND_VAL ~5 1 14 L17 #12 INIT_METHOD_CALL $rc "getReturnType" 15 L17 #13 DO_FCALL @6 16 L17 #14 SEND_VAR @6 2 17 L17 #15 DO_ICALL 18 L19 #16 NEW "ReflectionFunction" @8 19 L19 #17 SEND_VAL_EX "getB" 1 20 L19 #18 DO_FCALL 21 L19 #19 ASSIGN $rc @8 22 L20 #20 INIT_FCALL 112 "var_dump" 23 L20 #21 INIT_METHOD_CALL $rc "getReturnType" 24 L20 #22 DO_FCALL @11 25 L20 #23 CAST @11 ~12 26 L20 #24 SEND_VAL ~12 1 27 L20 #25 INIT_METHOD_CALL $rc "getReturnType" 28 L20 #26 DO_FCALL @13 29 L20 #27 SEND_VAR @13 2 30 L20 #28 DO_ICALL 31 L21 #29 RETURN 1
$rc->getReturnType() に対応するオペコードは #9 DO_FCALL であることがわかります
さて、単純化できるexecute_exから始めましょうInto:
01 // 最核心的执行opcode的函数 02 ZEND_API void execute_ex(zend_execute_data *ex) 03 { 04 ... 05 while (1) { 06 int ret; 07 if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0)) { 08 ... 09 } 10 11 } 12 ... 13 }
ここでのハンドラーの各オペコード op はハンドラーに対応します。例えば、DO_FCALL に対応するハンドラーは ZEND_DO_FCALL_SPEC_RETVAL_USED_HANDLER です (先ほど bt で表示されたスタックと同じです)
簡略化した疑似コードは次のとおりです。ご覧のとおり、この関数には fbc->internal_function.handler があります。ここでの external_function に対応する関数名は zim_reflection_function_getReturnType で、これは拡張モジュールで定義されている関数に対応します。ここにきて拡大期に入ったと言えるだろう。
上記は PHP カーネル解析 (7) - 拡張の内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) に注目してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

CakePHP でデータベースを操作するのは非常に簡単です。この章では、CRUD (作成、読み取り、更新、削除) 操作について理解します。

ファイルのアップロードを行うには、フォーム ヘルパーを使用します。ここではファイルアップロードの例を示します。

CakePHP は、PHP 用のオープンソース フレームワークです。これは、アプリケーションの開発、展開、保守をより簡単にすることを目的としています。 CakePHP は、強力かつ理解しやすい MVC のようなアーキテクチャに基づいています。モデル、ビュー、コントローラー

CakePHP へのログインは非常に簡単な作業です。使用する関数は 1 つだけです。 cronjob などのバックグラウンド プロセスのエラー、例外、ユーザー アクティビティ、ユーザーが実行したアクションをログに記録できます。 CakePHP でのデータのログ記録は簡単です。 log()関数が提供されています

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、
