原:PHP核心研究 函數的參數

來源:互聯網
上載者:User

在上一節中,分析了函數的定義,

函數的定義只是將函數名註冊到函數列表的過程.

下面繼續分析函數的參數.

如果沒有看就移步到>>原:PHP核心研究
函數的定義,

,

function $test($arg=11){

}

還是要看Lex的文法分析

[c]
unticked_function_declaration_statement:
function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); }
'(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
[/c]



parameter_list 就是分析參數的地方

經過分析找到瞭解析參數的函數

zend_do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, &$1, &$2, 0 TSRMLS_CC);

這裡先要說一下 用來儲存函數的結構體zend_arg_info

[c]
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; //參數是否允許為空白
zend_bool pass_by_reference; //參數是否為引用 也就是有沒有使用&
zend_bool return_reference; //函數自身是否是一個引用函數
int required_num_args; //最少傳遞幾個參數
} zend_arg_info;
[/c]




zend_do_receive_arg定義在Zend/zend_compile.c中

[c]
void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, const znode *initialization, znode *class_type, const znode *varname, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */
{
zend_op *opline;
zend_arg_info *cur_arg_info;//聲明一個函數結構指標
if (class_type->op_type == IS_CONST && //這裡是類相關處理 暫時跳過 講到類的時候再細說
跳過....
}

if (var->op_type == IS_CV &&
var->u.var == CG(active_op_array)->this_var &&
(CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
} else if (var->op_type == IS_VAR &&
CG(active_op_array)->scope &&
((CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) &&
(Z_TYPE(varname->u.constant) == IS_STRING) &&
(Z_STRLEN(varname->u.constant) == sizeof("this")-1) &&
(memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")) == 0)) {
zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
}
//建立一個op
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
CG(active_op_array)->num_args++;//參數的個數
opline->opcode = op; //中間碼 ZEND_RECV
opline->result = *var;//傳回值
opline->op1 = *offset;
if (op == ZEND_RECV_INIT) {
opline->op2 = *initialization;
} else {
CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
SET_UNUSED(opline->op2);
}
//複製參數列表到arr_info
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_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;
//這個時候 cur_arg_info->name的值就是 $arg;也就是我們傳遞過來的參數名
if (class_type->op_type != IS_UNUSED) {//跳過
有略過....
}
opline->result.u.EA.type |= EXT_TYPE_UNUSED;
}
[/c]

如果函數有N個參數,那麼 此函數就會執行N次

下一節將繼續介紹 函數的傳回值

原文出處:原:PHP核心研究
函數的參數

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.