原 PHP核心研究 函式的定義

2021-06-04 18:43:11 字數 3438 閱讀 6330

宣告:本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。

php技術部落格 在csdn也會同步更新的哦.

php中,函式的定義 是用關鍵字 function來定義的.

function hello($str)

在/zend/zend_language_parse.y中找到 關鍵字 t_function

[c]

function:

t_function

;[/c]

發現這個只是用來儲存當前函式設定的位置的..

而真正parse的地方在**?我找了很久沒找到,不得已 google了一下,才知道是在這裡

[c]

unticked_function_declaration_statement: //譯為 "函式宣告語句"

function is_reference t_string

'(' parameter_list ')' ''

;[/c]

is_reference :是引用嗎?

t_string :我們定義的函式名 ,等於hello

zend_do_begin_function_declaration:開始宣告函式.

parameter_list :是參數列

inner_statement_list :函式體語句

zend_do_end_function_declaration:結束宣告

乙個乙個來 先進 zend_do_begin_function_declaration看看,

比較長 一點點來看

[c]

void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode tsrmls_dc) /*

z_lval(fn_flags_znode->u.constant) |= zend_acc_abstract; /* propagates to the rest of the parser */

}fn_flags = z_lval(fn_flags_znode->u.constant); /* must be done *after* the above check */

} else

//類相關 跳過

if ((fn_flags & zend_acc_static) && (fn_flags & zend_acc_abstract) && !(cg(active_class_entry)->ce_flags & zend_acc_inte***ce))

//轉換為小寫

lcname = zend_str_tolower_dup(name, name_len);

orig_interactive = cg(interactive);

cg(interactive) = 0;

//初始化zend_op_array

/*要特別說明一下 在php裡面 函式有兩種一種是自定義函式:zend_user_function,

*一種是內建函式zend_internal_function,這裡我們是自定義函式所以 型別為zend_user_function

*/init_op_array(&op_array, zend_user_function, initial_op_array_size tsrmls_cc);

cg(interactive) = orig_interactive;

op_array.function_name = name; //函式名稱

op_array.return_reference = return_reference; //是否是引用函式

op_array.fn_flags |= fn_flags; //可能是標示宣告為類的方法

op_array.pass_rest_by_reference = 0; //所有引數都強制為引用?

op_array.prototype = null;//

op_array.line_start = zend_get_compiled_lineno(tsrmls_c);//開始行

if (is_method) else

//生成的中間**

opline->opcode = zend_declare_function;

//型別

opline->op1.op_type = is_const;

build_runtime_defined_function_key(&opline->op1.u.constant, lcname, name_len tsrmls_cc);

opline->op2.op_type = is_const;

opline->op2.u.constant.type = is_string;

opline->op2.u.constant.value.str.val = lcname;

opline->op2.u.constant.value.str.len = name_len;

z_set_refcount(opline->op2.u.constant, 1);

opline->extended_value = zend_declare_function;

//更新函式表的hashtable

zend_hash_update(cg(function_table), opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, &op_array, sizeof(zend_op_array), (void **) &cg(active_op_array));

}if (cg(compiler_options) & zend_compile_extended_info)

}if (cg(doc_comment))

zend_stack_push(&cg(labels_stack), (void *) &cg(labels), sizeof(hashtable*));

cg(labels) = null;

}[/c]

儲存自定義函式的結構如下

[c]

typedef union _zend_function common;

zend_op_array op_array;

zend_internal_function internal_function;

} zend_function;

[/c]

初始化op_array

生成 zend_op

生成的中間碼 zend_declare_function

更新函式表function_table

這樣 函式的定義就完了..

下一節詳細介紹 函式的引數.

原 PHP核心函式研究之 global

宣告 本文為斯人原創,全部為作者一一分析得之,有不對的地方望賜教。好久沒有寫部落格了 最近事挺多,換了工作,又搬了家.今天就來說說 我們經常用到的global語句吧.我們都知道,在函式體內宣告的變數,作用域只是當前函式體中,一般情況下是訪問不到外部宣告的變數的.因為全域性變數和區域性變數存放在不同的...

PHP核心函式研究之 intval

宣告 本文為斯人 原創,全部為作者一一分析得之,有不對的地方望賜教。趁熱打鐵 順便說說 intval函式.該函式好像我們用的最多的就是在post或者get某個引數的時候,將其強制轉換為int型,為了保證我們傳入到sql的時候是乙個整形.當然這只是其中一種用法.該函式接受兩個引數,第乙個是要轉換的字串...

PHP核心研究 記憶體管理1

memory limit 32m或者採用動態方式修改最大記憶體 ini set memory limit 128m 修改記憶體為128m memory get usage 目前php指令碼所用的記憶體大小 memory get peak usage 返回當前位置占用記憶體峰值,這樣就可以知道記憶體峰...