함수의 정의는 함수 목록에 함수 이름을 등록하는 과정일 뿐입니다.
함수의 매개변수 확인은 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 파일에서 이 두 함수의 구현을 찾으세요. 먼저 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. 내부 함수의 매개변수 공통 카운트 함수를 예로 들면 매개변수 처리 부분의 코드는 다음과 같습니다.
/* {{{ 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; } ... //省略 }여기에는 두 가지 작업이 포함됩니다. 하나는 매개변수 수를 가져오는 것이고, 다른 하나는 매개변수 목록을 구문 분석하는 것입니다. (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()를 사용하여 들어오는 매개변수에 대해 "원하는 만큼"을 표현합니다.두 번째 매개변수는 다음과 같습니다. TSRMLS_CC 매크로입니다. 세 번째 매개변수 type_spec은 수신할 것으로 예상되는 각 매개변수의 유형을 지정하는 데 사용되는 문자열로, printf에서 출력 형식을 지정하는
형식화된 문자열과 다소 유사합니다.
나머지 매개변수는 PHP 매개변수 값을 수신하는 데 사용하는 변수에 대한 포인터입니다. zend_parse_parameters()는 매개변수를 구문 분석하는 동안 매개변수 유형을 최대한 많이 변환하여 항상 예상 유형의 변수를 얻을 수 있도록 합니다위 내용은 PHP 사용자 정의 함수의 매개변수 전달에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!