ホームページ >バックエンド開発 >PHPチュートリアル >PHPカスタム関数のパラメータ受け渡しについての深い理解
関数の定義は、関数リストに関数名を登録するだけの処理です。
この関数のパラメーターのチェックは zend_do_receive_arg 関数を通じて実装されていることがわかります:CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args)); cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1]; cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len); cur_arg_info->name_len = varname->u.constant.value.str.len; cur_arg_info->array_type_hint = 0; cur_arg_info->allow_null = 1; cur_arg_info->pass_by_reference = pass_by_reference; cur_arg_info->class_name = NULL; cur_arg_info->class_name_len = 0;パラメーター全体が渡されます。 to 中間コードの arg_info フィールドへの代入操作が完了しました。重要な点は arg_info フィールドにあり、arg_info フィールドの構造は次のとおりです。
typedef struct _zend_arg_info { const char *name; /*参数的名称*/ zend_uint name_len; /*参数名称的长度*/ const char *class_name; /* 类名*/ zend_uint class_name_len; /*类名长度*/ zend_bool array_type_hint; /*数组类型提示*/ zend_bool allow_null; /*是否允许为NULLͺ*/ zend_bool pass_by_reference; /*是否引用传递*/ zend_bool return_reference; int required_num_args; } zend_arg_info;パラメーター値の受け渡しとパラメーターの受け渡しの違いは、中間コードの生成時に pass_by_reference パラメーターによって実現されます。 パラメータの数については、**zend_do_receive_argxx が実行されるたびに、中間コードに含まれる arg_nums フィールドが 1 ずつ増加します:
CG(active_op_array)->num_args++;そして、現在のパラメータのインデックスは CG(active_op_array)-> です。 ;num_args-1 .次のコード:
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];上記の解析は関数定義時のパラメータ設定に基づいており、これらのパラメータは固定されています。実際にプログラムを書く際には
変数パラメータを使用することがあります。このとき、関数 func_num_args と func_get_args を使用します。これらは 内部関数 として存在します。したがって、Zendzend_builtin_functions.c ファイルでこれら 2 つの関数の実装を見つけてください。まず func_num_args 関数の実装を見てみましょう。 コードは次のとおりです。
/* {{{ proto int func_num_args(void) Get the number of arguments that were passed to the function */ ZEND_FUNCTION(func_num_args) { zend_execute_data *ex = EG(current_execute_data)->prev_execute_data; if (ex && ex->function_state.arguments) { RETURN_LONG((long)(zend_uintptr_t)*(ex->function_state.arguments)); } else { zend_error(E_WARNING, "func_num_args(): Called from the global scope - no function context"); RETURN_LONG(-1); } } /* }}} */ex->function_state.arguments が存在し、関数が呼び出された場合、ex->function_state.arguments の変換された値が返されます。それ以外の場合はエラーが表示され、-1 が返されます。ここで最も重要なポイントは EG (current_execute_data) です。この変数には、現在実行中のプログラムまたは関数のデータが格納されています。なぜなら、この関数の呼び出しは関数に入った後に実行されるからです。関数の関連データはすべて前の実行プロセスにあるため、呼び出されるのは次のとおりです:
zend_execute_data *ex = EG(current_execute_data)->prev_execute_data;2. 内部関数のパラメータ 共通の count 関数を例にとると、パラメータ処理部分のコードは次のようになります。
/* {{{ proto int count(mixed var [, int mode]) Count the number of elements in a variable (usually an array) */ PHP_FUNCTION(count) { zval *array; long mode = COUNT_NORMAL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &array, &mode) == FAILURE) { return; } ... //省略 }これには 2 つの操作が含まれています。1 つはパラメーターの数を取得することで、もう 1 つはパラメーター リストを解析することです。 (1) パラメータの数を取得しますパラメータの数の取得は、次のように定義されている ZEND_NUM_ARGS() マクロによって実現されます:
#define ZEND_NUM_ARGS() (ht)ht は、Zend/zend.h ファイルで定義されたマクロ INTERNAL_FUNCTION_PARAMETERS にあります。 ht、以下の通り
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC(2) パラメータの解析リストPHPの内部関数はパラメータを解析する際にzend_parse_parametersを使用します。パラメーターの受信と処理の作業を大幅に簡素化できますが、可変パラメーターを扱う場合にはまだ少し弱いです。 次のように宣言されます:
ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...)最初のパラメータ num_args は、受信パラメータを「必要なだけ」表現するために ZEND_NUM_ARGS() をよく使用します 2 番目のパラメータは次のようになります。マクロ TSRMLS_CC です。 3 番目のパラメーター type_spec は、受け取ることが期待される各パラメーターの型を指定するために使用される文字列で、printf で出力形式を指定する
フォーマットされた文字列 に似ています。
残りのパラメーターは、PHP パラメーター値を受け取るために使用する変数へのポインターです。 zend_parse_parameters() は、パラメーターの解析中に可能な限りパラメーターの型を変換し、常に期待される型の変数を取得できるようにします以上がPHPカスタム関数のパラメータ受け渡しについての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。