首页 > 代码库 > PHP内核两大流程之请求处理

PHP内核两大流程之请求处理

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; // 鍒濆鍖栭敊璇姤鍛婂彉閲? 
          
        // 涓烘墽琛屾爤鍒嗛厤绌洪棿  
        if (op_array->T < TEMP_VAR_STACK_LIMIT) {  
            EX(Ts) = (temp_variable *) do_alloca(sizeof(temp_variable) * op_array->T);  
        } else {  
            EX(Ts) = (temp_variable *) safe_emalloc(sizeof(temp_variable), op_array->T, 0);  
        }  
        // 涓轰复鏃跺彉閲忓垎閰嶇┖闂村苟鍒濆鍖栬繖浜涚┖闂? 
        EX(CVs) = (zval***)do_alloca(sizeof(zval**) * op_array->last_var);  
        memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);  
          
        EX(op_array) = op_array;  
          
        // 鍒囨崲鎵ц涓婁笅鏂? 
        EX(original_in_execution) = EG(in_execution);  
        EX(symbol_table) = EG(active_symbol_table);  
        EX(prev_execute_data) = EG(current_execute_data); // 灏嗗綋鍓嶅叏灞€鍙橀噺涓殑鎵ц鏁版嵁鍘嬫爤  
        EG(current_execute_data) = &execute_data; // 灏嗗綋鍓嶆墽琛屼笂涓嬫枃鍘嬫爤  
      
        EG(in_execution) = 1;  
        // 鍒濆鍖栫涓€涓寚浠?opcode)  
        /* 
        #define ZEND_VM_SET_OPCODE(new_op) \ 
        CHECK_SYMBOL_TABLES() \ 
        EX(opline) = new_op 
         
        execute_data.opline 涓哄綋鍓嶆墽琛岀殑 opcode 
        */  
        if (op_array->start_op) {  
            ZEND_VM_SET_OPCODE(op_array->start_op);  
        } else {  
            ZEND_VM_SET_OPCODE(op_array->opcodes);  
        }  
      
        if (op_array->uses_this && EG(This)) {  
            EG(This)->refcount++; /* For $this pointer */  
            if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {  
                EG(This)->refcount--;  
            }  
        }  
      
        // 灏嗗瓨鍌╫pline鐨勫唴瀛樺湴鍧€璧嬬粰 executor_globals.online_ptr 锛屽彲浠ュ疄鏃惰窡韪猳pcode鐨勬墽琛? 
        EG(opline_ptr) = &EX(opline);  
      
        EX(function_state).function = (zend_function *) op_array;  
        EG(function_state_ptr) = &EX(function_state);  
    #if ZEND_DEBUG  
        /* function_state.function_symbol_table is saved as-is to a stack, 
         * which is an intentional UMR.  Shut it up if we're in DEBUG. 
         */  
        EX(function_state).function_symbol_table = NULL;  
    #endif  
          
        while (1) {  
    #ifdef ZEND_WIN32  
            if (EG(timed_out)) {  
                zend_timeout(0);  
            }  
    #endif  
              
            // 寰幆璋冪敤姣忎釜opline鐨?handler 鍑芥暟锛屽鏋滄槸鎺ㄥ嚭鍑芥暟鐨勮瘽锛岃繑鍥炲€煎ぇ浜?锛屽氨閫€鍑? 
            if (EX(opline)->handler(&execute_data TSRMLS_CC) > 0) {  
          return;  
            }  
      
        }  
        zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");  
    }  

PHP内核两大流程之请求处理