首页 > 编程知识 正文

sql语法基础知识,mysql语句大全及用法

时间:2023-05-06 16:23:05 阅读:114710 作者:3372

修改文章,以前没有说明问题。

主要说明PHP的执行流程。 与函数的执行过程有关。 PHP的函数是使PHP强大的特征之一,暂时不讨论类。 PHP的范围控制只有两处。 是函数和类。 实际上,我觉得函数控制作用域的概念更多。

函数包括用户定义的函数和内部函数。 内部函数是php用c或c写的。 在此分析时,范围切换无关紧要。 在模块初始化时将eg(function_table )加载到全局函数表中。

内部函数、用户定义函数和op_array三种数据结构如下:

struct _ Zend _ op _ array {/*公共元素*/Zend _ uchar type; char *function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; Zend _ bool pass _ rest _ by _ reference; unsigned char return_reference;/* endofcommonelements */Zend _ bool done _ pass _ two; zend_uint *refcount; zend_op *opcodes; zend_uint last,size; zend_compiled_variable *vars; int last_var,size_var; zend_uint T; Zend _ brk _ cont _ element * brk _ cont _ array; int last_brk_cont; int current_brk_cont; Zend _ try _ catch _ element * try _ catch _ array; int last_try_catch;/* staticvariablessupport */hashtable * static _ variables; zend_op *start_op; int backpatch_count; zend_uint this_var; char *filename; zend_uint line_start; zend_uint line_end; char *doc_comment; zend_uint doc_comment_len; zend_uint early_binding;/* thelinkedlistofdelayeddeclarations */void * reserved [ Zend _ max _ reserved _ resources ]; (; typedef struct _ Zend _ internal _ function {/*公共元素*/Zend _ uchar type; char * function_name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; Zend _ bool pass _ rest _ by _ reference; unsigned char return_reference;/* endofcommonelements */void (* handler ) (INTERNAL_FUNCTION_PARAMETERS ); struct _ Zend _ module _ entry * module; } zend_internal_function; typedef union _ Zend _ function { Zend _ uchar type;/* mustbethefirstelementofthisstruct! * /结构{ Zend _ uchar type;/* never used */char * function _ name; zend_class_entry *scope; zend_uint fn_flags; union _zend_function *prototype; zend_uint num_args; zend_uint required_num_args; zend_arg_info *arg_info; Zend _ bool pass _ rest _ by _ reference; unsigned char return_reference; }公共; zend_op_array op_array; Zend _ internal _ function internal _ function; } zend_function; typedef struct _ Zend _ function _ state { Zend _ function * function; void **arguments; } zend_function_state

这三种数据结构可以相互转换。 上面也显示了_zend_function_state的数据结构。 说明将op_array的function分配给执行数据_zend_execut

e_data 的function_state字段的 function,从而将普通代码中切入一个函数,对于作用域的切换稍后说明。

在excute 执行过程中,有EX(function_state).function = (zend_function *) op_array;可以说明一切。

一个重要的数据结构:

struct _zend_execute_data {struct _zend_op *opline;zend_function_state function_state;zend_function *fbc; /* Function Being Called */zend_class_entry *called_scope;zend_op_array *op_array;zval *object;union _temp_variable *Ts;zval ***CVs;HashTable *symbol_table;struct _zend_execute_data *prev_execute_data;zval *old_error_reporting;zend_bool nested;zval **original_return_value;zend_class_entry *current_scope;zend_class_entry *current_called_scope;zval *current_this;zval *current_object;struct _zend_op *call_opline;}

用于保存执行期间的数据,在作用域切换的时候起至关重要的作用。

ZEND_API void execute(zend_op_array *op_array TSRMLS_DC){zend_execute_data *execute_data;zend_bool nested = 0;zend_bool original_in_execution = EG(in_execution);if (EG(exception)) {return;}EG(in_execution) = 1;zend_vm_enter:/* Initialize execute_data */execute_data = (zend_execute_data *)zend_vm_stack_alloc(ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));EX(fbc) = NULL;EX(called_scope) = NULL;EX(object) = NULL;EX(old_error_reporting) = NULL;EX(op_array) = op_array;EX(symbol_table) = EG(active_symbol_table);EX(prev_execute_data) = EG(current_execute_data);EG(current_execute_data) = execute_data;EX(nested) = nested;nested = 1;if (op_array->start_op) {ZEND_VM_SET_OPCODE(op_array->start_op);} else {ZEND_VM_SET_OPCODE(op_array->opcodes);}if (op_array->this_var != -1 && EG(This)) { Z_ADDREF_P(EG(This)); /* For $this pointer */if (!EG(active_symbol_table)) {EX(CVs)[op_array->this_var] = (zval**)EX(CVs) + (op_array->last_var + op_array->this_var);*EX(CVs)[op_array->this_var] = EG(This);} else {if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX(CVs)[op_array->this_var])==FAILURE) {Z_DELREF_P(EG(This));}}}EG(opline_ptr) = &EX(opline);EX(function_state).function = (zend_function *) op_array;EX(function_state).arguments = NULL;while (1) { int ret;#ifdef ZEND_WIN32if (EG(timed_out)) {zend_timeout(0);}#endifif ((ret = EX(opline)->handler(execute_data TSRMLS_CC)) > 0) {switch (ret) {case 1:EG(in_execution) = original_in_execution;return;case 2:op_array = EG(active_op_array);goto zend_vm_enter;case 3:execute_data = EG(current_execute_data);default:break;}}}zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");}

执行期间 有EX(prev_execute_data) = EG(current_execute_data);会保存一下现场,

然后EG(current_execute_data) = execute_data;

当执行到函数的op_array时,EG(active_op_array) = &EX(function_state).function->op_array;

会执行到

case 2:

op_array = EG(active_op_array);

goto zend_vm_enter;

当函数将要执行完毕或者返回的时候,可以主动调用return 或者PHP 会自动放回一个NULL,然后是zend_do_return 生成 ZEND_RETURN的opcode ,根据类型不同会调用几个不同的函数,但总之会调用一个名为zend_leave_helper_SPEC 的函数,其中:

EG(current_execute_data) = EX(prev_execute_data);会将返回以前的场景,保证回到执行函数以前的作用域。

个人觉得关键的是以上的一些数据结构,以及相互之间的联系。

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。