PHPカーネルの內(nèi)部構(gòu)造を深く理解する(5)関數(shù)
Jun 13, 2016 pm 12:28 PM
PHP カーネルの內(nèi)部構(gòu)造を深く理解する (5) 関數(shù)
PHP 関數(shù)には、ユーザー定義関數(shù)、內(nèi)部関數(shù) (print_r count...)、匿名関數(shù)、変數(shù)関數(shù) ($func = 'print_r) が含まれます。 '; $ func(array('a','b'));)
PHP カーネルのソースコード內(nèi)の関數(shù)は次の種類に分類されます
<span style="color: #0000ff;">#define</span> ZEND_INTERNAL_FUNCTION 1<span style="color: #0000ff;">#define</span> ZEND_USER_FUNCTION 2 <span style="color: #0000ff;">#define</span> ZEND_OVERLOADED_FUNCTION 3<span style="color: #0000ff;">#define</span> ZEND_EVAL_CODE 4<span style="color: #0000ff;">#define</span> ZEND_OVERLOADED_FUNCTION_TEMPORARY 5
1. ユーザー関數(shù) (ZEND_USER_FUNCTION)
PHP 実裝では、明示的な戻り値がない場合でも、関數(shù)は必ずしも明示的な戻り値を持ちません。 PHP カーネルは NULL を返します。
実行プロセス中、ZEND はランタイム情報(bào)を _zend_execute_data に保存します。
<span style="color: #0000ff;">struct</span><span style="color: #000000;"> _zend_execute_data { </span><span style="color: #008000;">//</span><span style="color: #008000;">...省略部分代碼</span><span style="color: #000000;"> zend_function_state function_state; zend_function </span>*fbc; <span style="color: #008000;">/*</span><span style="color: #008000;"> Function Being Called </span><span style="color: #008000;">*/</span> <span style="color: #008000;">//</span><span style="color: #008000;">...省略部分代碼</span>};
プログラムの初期化プロセス中に、 function_state も初期化されます。 function_state は次のもので構(gòu)成されます。 2 つの部分:
typedef <span style="color: #0000ff;">struct</span><span style="color: #000000;"> _zend_function_state { zend_function </span>*<span style="color: #000000;">function; </span><span style="color: #0000ff;">void</span> **<span style="color: #000000;">arguments;} zend_function_state;</span>
*arguments は関數(shù)パラメーターへのポインターであり、関數(shù)本體は *function に格納されます。これは zend_function 構(gòu)造體であり、最終的にすべての情報(bào)が格納されます。ユーザー定義関數(shù)について 具體的な構(gòu)造は次のとおりです:
<span style="color: #000000;">typedef union _zend_function { zend_uchar type; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> MUST be the first element of this struct! </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">struct</span><span style="color: #000000;"> { zend_uchar type; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> never used </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">char</span> *function_name; <span style="color: #008000;">//</span><span style="color: #008000;">函數(shù)名稱</span> zend_class_entry *scope; <span style="color: #008000;">//</span><span style="color: #008000;">函數(shù)所在的類作用域</span> zend_uint fn_flags; <span style="color: #008000;">//</span><span style="color: #008000;">函數(shù)類型,如用戶自定義則為 #define </span>ZEND_USER_FUNCTION <span style="color: #800080;">2</span><span style="color: #000000;"> union _zend_function </span>*prototype; <span style="color: #008000;">//</span><span style="color: #008000;">函數(shù)原型</span> zend_uint num_args; <span style="color: #008000;">//</span><span style="color: #008000;">參數(shù)數(shù)目</span> zend_uint required_num_args; <span style="color: #008000;">//</span><span style="color: #008000;">需要的參數(shù)數(shù)目</span> zend_arg_info *arg_info; <span style="color: #008000;">//</span><span style="color: #008000;">參數(shù)信息指針</span><span style="color: #000000;"> zend_bool pass_rest_by_reference; unsigned </span><span style="color: #0000ff;">char</span> return_reference; <span style="color: #008000;">//</span><span style="color: #008000;">返回值</span><span style="color: #000000;"> } common; zend_op_array op_array; </span><span style="color: #008000;">//</span><span style="color: #008000;">函數(shù)中的操作</span><span style="color: #000000;">? zend_internal_function internal_function; } zend_function;</span>
zend_function の構(gòu)造內(nèi)の op_array は、関數(shù)が呼び出されるときに、関數(shù)內(nèi)のすべての操作を格納します。 ZEND は、この op_array 內(nèi)の opline を 1 つずつ順番に実行し、最終結(jié)果を返します。関數(shù)の定義と実行は分離されており、関數(shù)は獨(dú)立した実行単位として存在できます。
2. 內(nèi)部関數(shù) (ZEND_INTERNAL_FUNCTION)
ZEND_INTERNAL_FUNCTION 関數(shù)は、c/c で記述された拡張機(jī)能または Zend/PHP カーネルによって提供されます。直接実行できる関數(shù)。內(nèi)部関數(shù)の構(gòu)造は次のとおりです。
typedef <span style="color: #0000ff;">struct</span><span style="color: #000000;"> _zend_internal_function { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> Common elements </span><span style="color: #008000;">*/</span><span style="color: #000000;"> zend_uchar type; </span><span style="color: #0000ff;">char</span> *<span style="color: #000000;"> function_name; zend_class_entry </span>*<span style="color: #000000;">scope; zend_uint fn_flags; union _zend_function </span>*<span style="color: #000000;">prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info </span>*<span style="color: #000000;">arg_info; zend_bool pass_rest_by_reference; unsigned </span><span style="color: #0000ff;">char</span><span style="color: #000000;"> return_reference; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> END of common elements </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">void</span> (*<span style="color: #000000;">handler)(INTERNAL_FUNCTION_PARAMETERS); </span><span style="color: #0000ff;">struct</span> _zend_module_entry *<span style="color: #000000;">module;} zend_internal_function;</span>
モジュールが初期化されると、ZE はロードされた各拡張モジュールを走査し、function_entry を追加します。モジュール內(nèi) 指定された関數(shù) (モジュール>関數(shù)) ごとに、zend_internal_function 構(gòu)造體を作成し、そのタイプを ZEND_INTERNAL_FUNCTION に設(shè)定し、この構(gòu)造體をグローバル関數(shù)テーブル (HashTable 構(gòu)造體) に入力します。関數(shù)の設(shè)定と登録については、Zend/zene_API を參照してください。 c ファイルの zend_register_function 関數(shù)は、関數(shù)ページの処理に加えて、これらのマジック メソッドを含むクラス メソッドも処理します。
內(nèi)部関數(shù)の構(gòu)造は基本的にユーザー定義関數(shù)の構(gòu)造と似ていますが、いくつかの違いがあります。
- 呼び出しメソッド、ハンドラーフィールド、それが ZEND_INTERNAL_FUNCTION の場合、ZEND はこの関數(shù)を?qū)g行するには、zend_internal_function.handler を通じて zend_execute_internal を呼び出します。ユーザー定義関數(shù)は中間コードを生成し、その中間コードを?qū)潖辘工毳幞渐氓嗓衰蕙氓驻筏坪簸映訾贡匾ⅳ辘蓼埂?
- 組み込み関數(shù)には、どのモジュールに屬しているかを示す追加のモジュール フィールドが構(gòu)造內(nèi)にあります。拡張モジュールごとに異なる
- type フィールドがあります。ユーザー定義関數(shù)では、type フィールドはほとんど役に立ちませんが、組み込み関數(shù)の type フィールドは、いくつかの內(nèi)部関數(shù)間の區(qū)別として機(jī)能します。
3. 変數(shù)関數(shù)
変數(shù)名の後に括弧がある場合、PHP は同じ名前の関數(shù)を検索します。を変數(shù)の値として指定し、実行してみます。
変數(shù)関數(shù) $func
$func = <span style="color: #800000;">'</span><span style="color: #800000;">print_r</span><span style="color: #800000;">'</span><span style="color: #000000;">;$func(</span><span style="color: #800000;">'</span><span style="color: #800000;">i am print_r function.</span><span style="color: #800000;">'</span>);
コンパイル済み中間コード
function name: (<span style="color: #0000ff;">null</span><span style="color: #000000;">)number of ops: </span><span style="color: #800080;">9</span><span style="color: #000000;">compiled vars: </span>!<span style="color: #800080;">0</span> =<span style="color: #000000;"> $funcline # </span>* op fetch ext <span style="color: #0000ff;">return</span><span style="color: #000000;"> operands</span>-------------------------------------------------------------------------------- <span style="color: #800080;">2</span> <span style="color: #800080;">0</span> ><span style="color: #000000;"> EXT_STMT </span><span style="color: #800080;">1</span> ASSIGN !<span style="color: #800080;">0</span><span style="color: #000000;">, </span><span style="color: #800000;">'</span><span style="color: #800000;">print_r</span><span style="color: #800000;">'</span> <span style="color: #800080;">3</span> <span style="color: #800080;">2</span><span style="color: #000000;"> EXT_STMT </span><span style="color: #800080;">3</span> INIT_FCALL_BY_NAME !<span style="color: #800080;">0</span> <span style="color: #800080;">4</span><span style="color: #000000;"> EXT_FCALL_BEGIN </span><span style="color: #800080;">5</span><span style="color: #000000;"> SEND_VAL </span><span style="color: #800000;">'</span><span style="color: #800000;">i+am+print_r+function.</span><span style="color: #800000;">'</span> <span style="color: #800080;">6</span> DO_FCALL_BY_NAME <span style="color: #800080;">1</span> <span style="color: #800080;">7</span><span style="color: #000000;"> EXT_FCALL_END </span><span style="color: #800080;">8</span> > RETURN 1
內(nèi)部関數(shù)
print_r(<span style="color: #800000;">'</span><span style="color: #800000;">i am print_r function.</span><span style="color: #800000;">'</span>);
コンパイルされた中間コード
function name: (<span style="color: #0000ff;">null</span><span style="color: #000000;">)number of ops: </span><span style="color: #800080;">6</span><span style="color: #000000;">compiled vars: noneline # </span>* op fetch ext <span style="color: #0000ff;">return</span><span style="color: #000000;"> operands</span>--------------------------------------------------------------------------------- <span style="color: #800080;">2</span> <span style="color: #800080;">0</span> ><span style="color: #000000;"> EXT_STMT </span><span style="color: #800080;">1</span><span style="color: #000000;"> EXT_FCALL_BEGIN </span><span style="color: #800080;">2</span><span style="color: #000000;"> SEND_VAL </span><span style="color: #800000;">'</span><span style="color: #800000;">i+am+print_r+function.</span><span style="color: #800000;">'</span> <span style="color: #800080;">3</span> DO_FCALL <span style="color: #800080;">1</span> <span style="color: #800000;">'</span><span style="color: #800000;">print_r</span><span style="color: #800000;">'</span> <span style="color: #800080;">4</span><span style="color: #000000;"> EXT_FCALL_END </span><span style="color: #800080;">5</span> > RETURN <span style="color: #800080;">1</span>
比較すると、この 2 つの中間コードの呼び出しにはいくつかの違いがあることがわかります。変數(shù)関數(shù)は DO_FCALL_BY_NAME です。 while 內(nèi)部関數(shù)は DO_FCALL です。これは構(gòu)文解析中に決定されます。Zend/zend_complie.c ファイルの zend_do_end_function_call 関數(shù)のコードの一部を參照してください。
<span style="color: #0000ff;">if</span> (!is_method && !is_dynamic_fcall && function_name->op_type==<span style="color: #000000;">IS_CONST) { opline</span>->opcode =<span style="color: #000000;"> ZEND_DO_FCALL; opline</span>->op1 = *<span style="color: #000000;">function_name; ZVAL_LONG(</span>&opline-><span style="color: #000000;">op2.u.constant, zend_hash_func(Z_STRVAL(function_name</span>->u.constant), Z_STRLEN(function_name->u.constant) + <span style="color: #800080;">1</span><span style="color: #000000;">)); } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { opline</span>->opcode =<span style="color: #000000;"> ZEND_DO_FCALL_BY_NAME; SET_UNUSED(opline</span>-><span style="color: #000000;">op1); }</span>
メソッドではなく、これは動的呼び出しではなく、関數(shù)の名前は文字列変數(shù)であり、生成される中間コードは ZEND_DO_FCALL です。それ以外の場合は、ZEND_DO_FCALL_BY_NAME です。また、変數(shù)関數(shù)はコールバック関數(shù)として使用され、その処理プロセスは Zend/zend_complie.c ファイルの zend_do_pass_param 関數(shù)內(nèi)にあり、最終的に中間コードの実行時に ZEND_SEND_VAL_SPEC_CONST_HADNLER などの関數(shù)に反映されます。
4. 匿名関數(shù)
匿名関數(shù)は、指定された識別子を必要としない関數(shù)の一種です。関數(shù)またはサブルーチンと呼ばれる場合、匿名関數(shù)をパラメータとして他の関數(shù)に渡すことができます。

ホットAIツール

Undress AI Tool
脫衣畫像を無料で

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

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

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

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

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

ゼンドスタジオ 13.0.1
強(qiáng)力な PHP 統(tǒng)合開発環(huán)境

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

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

ファンクションとは、関數(shù)を意味します。これは、特定の関數(shù)を備えた再利用可能なコード ブロックです。プログラムの基本コンポーネントの 1 つです。入力パラメータを受け取り、特定の操作を?qū)g行し、結(jié)果を返すことができます。その目的は、再利用可能なコード ブロックをカプセル化することです。コードの再利用性と保守性を向上させるコード。

PHP 実裝フレームワーク: ZendFramework 入門チュートリアル ZendFramework は、PHP によって開発されたオープン ソースの Web サイト フレームワークであり、現(xiàn)在 ZendTechnologies によって保守されています。ZendFramework は、MVC デザイン パターンを採用し、Web2.0 アプリケーションと Web サーブの実裝に役立つ一連の再利用可能なコード ライブラリを提供します。 。 ZendFramework は PHP 開発者に非常に人気があり、尊敬されており、幅広い機(jī)能を備えています。

Zend Framework でのアクセス許可制御に ACL (AccessControlList) を使用する方法 はじめに: Web アプリケーションでは、アクセス許可制御は重要な機(jī)能です。これにより、ユーザーはアクセスを許可されたページと機(jī)能にのみアクセスできるようになり、不正アクセスが防止されます。 Zend フレームワークは、ACL (AccessControlList) コンポーネントを使用してアクセス許可制御を?qū)g裝する便利な方法を提供します。この記事では、Zend Framework で ACL を使用する方法を紹介します。

MySQL.proc テーブルの役割と機(jī)能の詳細(xì)な説明。MySQL は人気のあるリレーショナル データベース管理システムです。開発者が MySQL を使用する場合、多くの場合、ストアド プロシージャ (StoredProcedure) の作成と管理が必要になります。 MySQL.proc テーブルは非常に重要なシステム テーブルであり、ストアド プロシージャの名前、定義、パラメータなど、データベース內(nèi)のすべてのストアド プロシージャに関連する情報(bào)が保存されます。この記事では、MySQL.proc テーブルの役割と機(jī)能について詳しく説明します。

この記事では、Python の enumerate() 関數(shù)と「enumerate()」関數(shù)の目的について學(xué)びます。 enumerate() 関數(shù)とは何ですか? Python の enumerate() 関數(shù)は、データ コレクションをパラメータとして受け取り、列挙オブジェクトを返します。列挙オブジェクトはキーと値のペアとして返されます。キーは各項(xiàng)目に対応するインデックス、値は項(xiàng)目です。構(gòu)文 enumerate(iterable,start) パラメータ iterable - 渡されたデータ コレクションは、iterablestart と呼ばれる列挙オブジェクトとして返すことができます。 - 名前が示すように、列挙オブジェクトの開始インデックスは start によって定義されます。無視したら

php提交表單通過后,彈出的對話框怎樣在當(dāng)前頁彈出php提交表單通過后,彈出的對話框怎樣在當(dāng)前頁彈出而不是在空白頁彈出?想實(shí)現(xiàn)這樣的效果:而不是空白頁彈出:------解決方案--------------------如果你的驗(yàn)證用PHP在后端,那么就用Ajax;僅供參考:HTML code

インターネットの発展に伴い、SOA (サービス指向アーキテクチャ) は、今日のエンタープライズ レベルのシステムにおける重要な技術(shù)アーキテクチャになりました。 SOA アーキテクチャのサービスは再利用、再編成、拡張が可能であると同時に、システム開発とメンテナンスのプロセスも簡素化されます。広く使用されている Web プログラミング言語として、PHP は SOA を?qū)g裝するための関數(shù)ライブラリもいくつか提供しています。次に、PHP で SOA 関數(shù)を使用する方法を詳しく説明します。 1. SOA の基本概念 SOA は分散システム開発の考え方とアーキテクチャです。

clearstatcache() 関數(shù)は、ファイル ステータス キャッシュをクリアするために使用されます。 PHP は、次の関數(shù)によって返された情報(bào)をキャッシュします。 -stat()lstat()file_exists()is_writable()is_readable()is_executable()is_file()is_dir()filegroup()fileowner()filesize()filetype()fileperms()より良いパフォーマンスを提供するため。構(gòu)文 voidclearstatecache() パラメータ NA 戻り値 clearstatcache(
