Home  >  Article  >  Backend Development  >  Request processing of two major processes in PHP kernel_PHP tutorial

Request processing of two major processes in PHP kernel_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:13:32810browse

Request processing of two major processes in PHP core

static int php_handler(request_rec *r)
{
	/* Initiliaze the context */
        php_struct * volatile ctx;
        void *conf;
        apr_bucket_brigade * volatile brigade;
        apr_bucket *bucket;
        apr_status_t rv;
        request_rec * volatile parent_req = NULL;
        TSRMLS_FETCH();

	......

        zend_file_handle zfd;

        zfd.type = ZEND_HANDLE_FILENAME;
        zfd.filename = (char *) r->filename;
        zfd.free_filename = 0;
        zfd.opened_path = NULL;

	zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &zfd);

	......
}

ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
{
	......

	EG(active_op_array) = \
	zend_compile_file(file_handle, type TSRMLS_CC);

	......

	zend_execute(EG(active_op_array) TSRMLS_CC);

	......
}

ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)  
{  
    // 初始化执行上下文  
    zend_execute_data execute_data;  
  
    // 如果有异常就退出执行  
    if (EG(exception)) {  
        return;  
    }  
  
    /* Initialize execute_data */  
    EX(fbc) = NULL; // 初始化正在调用的函数  
    EX(object) = NULL; // 初始化正在调用的对象  
    EX(old_error_reporting) = NULL; // 初始化错误报告变量  
      
    // 为执行栈分配空间  
&#160; &#160; if (op_array->T < TEMP_VAR_STACK_LIMIT) { &#160;
&#160; &#160; &#160; &#160; EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T); &#160;
&#160; &#160; } else { &#160;
&#160; &#160; &#160; &#160; EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0); &#160;
&#160; &#160; } &#160;
&#160; &#160; // 为临时变量分配空间并初始化这些空间 &#160;
&#160; &#160; EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var); &#160;
&#160; &#160; memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); &#160;
&#160; &#160; &#160;&#160;
&#160; &#160; EX(op_array) = op_array; &#160;
&#160; &#160; &#160;&#160;
&#160; &#160; // 切换执行上下文 &#160;
&#160; &#160; EX(original_in_execution) = EG(in_execution); &#160;
&#160; &#160; EX(symbol_table) = EG(active_symbol_table); &#160;
&#160; &#160; EX(prev_execute_data) = EG(current_execute_data); // 将当前全局变量中的执行数据压栈 &#160;
&#160; &#160; EG(current_execute_data) = &execute_data; // 将当前执行上下文压栈 &#160;
&#160;&#160;
&#160; &#160; EG(in_execution) = 1; &#160;
&#160; &#160; // 初始化第一个指令(opcode) &#160;
&#160; &#160; /*&#160;
&#160; &#160; #define ZEND_VM_SET_OPCODE(new_op) \&#160;
&#160; &#160; CHECK_SYMBOL_TABLES() \&#160;
&#160; &#160; EX(opline) = new_op&#160;
&#160; &#160; &#160;
&#160; &#160; execute_data.opline 为当前执行的 opcode&#160;
&#160; &#160; */ &#160;
&#160; &#160; if (op_array->start_op) { &#160;
&#160; &#160; &#160; &#160; ZEND_VM_SET_OPCODE(op_array->start_op); &#160;
&#160; &#160; } else { &#160;
&#160; &#160; &#160; &#160; ZEND_VM_SET_OPCODE(op_array->opcodes); &#160;
&#160; &#160; } &#160;
&#160;&#160;
&#160; &#160; if (op_array->uses_this && EG(This)) { &#160;
&#160; &#160; &#160; &#160; EG(This)->refcount++; /* For $this pointer */ &#160;
&#160; &#160; &#160; &#160; if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) { &#160;
&#160; &#160; &#160; &#160; &#160; &#160; EG(This)->refcount--; &#160;
&#160; &#160; &#160; &#160; } &#160;
&#160; &#160; } &#160;
&#160;&#160;
&#160; &#160; // 将存储opline的内存地址赋给 executor_globals.online_ptr ,可以实时跟踪opcode的执行 &#160;
&#160; &#160; EG(opline_ptr) = &EX(opline); &#160;
&#160;&#160;
&#160; &#160; EX(function_state).function = (zend_function *) op_array; &#160;
&#160; &#160; EG(function_state_ptr) = &EX(function_state); &#160;
#if ZEND_DEBUG &#160;
&#160; &#160; /* function_state.function_symbol_table is saved as-is to a stack,&#160;
&#160; &#160; &#160;* which is an intentional UMR. &#160;Shut it up if we&#39;re in DEBUG.&#160;
&#160; &#160; &#160;*/ &#160;
&#160; &#160; EX(function_state).function_symbol_table = NULL; &#160;
#endif &#160;
&#160; &#160; &#160;&#160;
&#160; &#160; while (1) { &#160;
#ifdef ZEND_WIN32 &#160;
&#160; &#160; &#160; &#160; if (EG(timed_out)) { &#160;
&#160; &#160; &#160; &#160; &#160; &#160; zend_timeout(0); &#160;
&#160; &#160; &#160; &#160; } &#160;
#endif &#160;
&#160; &#160; &#160; &#160; &#160;&#160;
&#160; &#160; &#160; &#160; // 循环调用每个opline的 handler 函数,如果是推出函数的话,返回值大于0,就退出 &#160;
&#160; &#160; &#160; &#160; if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) { &#160;
&#160; &#160; &#160; return; &#160;
&#160; &#160; &#160; &#160; } &#160;
&#160;&#160;
&#160; &#160; } &#160;
&#160; &#160; zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn&#39;t happen"); &#160;
} &#160;

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/914780.htmlTechArticleRequest processing of the two major processes in the PHP core static int php_handler(request_rec *r){/* Initiliaze the context */ php_struct * volatile ctx; void *conf; apr_bucket_brigade * volatile brigad...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn