php-echo原理

來源:互聯網
上載者:User

標籤:style   blog   http   io   ar   color   os   sp   for   

1.文法分析

unticked_statement:|    T_ECHO echo_expr_list ;;echo_expr_list:        echo_expr_list , expr { zend_do_echo(&$3 TSRMLS_CC); }    |    expr                    { zend_do_echo(&$1 TSRMLS_CC); };expr:        r_variable                    { $$ = $1; }    |    expr_without_variable        { $$ = $1; };r_variable:    variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$ = $1; };variable:            |    base_variable_with_function_calls { $$ = $1; };base_variable_with_function_calls:        base_variable                { $$ = $1; }    ;reference_variable:    |    compound_variable            { zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(&$$, &$1, 1 TSRMLS_CC); };compound_variable:        T_VARIABLE            { $$ = $1; }    |    $ { expr }    { $$ = $3; };

 

2.編譯產生opcode

void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */{    zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);    opline->opcode = ZEND_ECHO;    SET_NODE(opline->op1, arg);    SET_UNUSED(opline->op2);}

 

3.執行已經產生的opcode

static int ZEND_FASTCALL  ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS){    USE_OPLINE    zval *z;    SAVE_OPLINE();    z = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC); //這個z已經是值了    if (IS_CV == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {        INIT_PZVAL(z);    }    zend_print_variable(z);    CHECK_EXCEPTION();    ZEND_VM_NEXT_OPCODE();}

 

static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC){    zval ***ptr = &CV(var); //EG(active_op_array).vars[key]該結果是個zend_compile_variable ,其中key為znod_op的變數var,是個數字,可理解為第幾個變數,最終在EG(active_sysbole_table)中取出資料,放到EX(CVs)[key]中    if (UNEXPECTED(*ptr == NULL)) {        return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);    }    return **ptr;}static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_R(zval ***ptr, zend_uint var TSRMLS_DC){    zend_compiled_variable *cv = &CV_DEF_OF(var);    if (!EG(active_symbol_table) ||        zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {        zend_error(E_NOTICE, "Undefined variable: %s", cv->name);        return &EG(uninitialized_zval_ptr);    }    return *ptr;}

 

ZEND_API int zend_print_variable(zval *var) {    return zend_print_zval(var, 0);}ZEND_API int zend_print_zval(zval *expr, int indent) /* {{{ */{    return zend_print_zval_ex(zend_write, expr, indent);}ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent) /* {{{ */{    zval expr_copy;    int use_copy;    zend_make_printable_zval(expr, &expr_copy, &use_copy);    if (use_copy) {        expr = &expr_copy;    }    if (Z_STRLEN_P(expr) == 0) { /* optimize away empty strings */        if (use_copy) {            zval_dtor(expr);        }        return 0;    }    write_func(Z_STRVAL_P(expr), Z_STRLEN_P(expr));    if (use_copy) {        zval_dtor(expr);    }    return Z_STRLEN_P(expr);}int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules){    zend_utility_functions zuf;    zend_utility_values zuv;    int retval = SUCCESS, module_number=0;    /* for REGISTER_INI_ENTRIES() */    。。。。。。。。。。。。。。    sapi_module = *sf;    php_output_startup();    zuf.error_function = php_error_cb;    zuf.printf_function = php_printf;    zuf.write_function = php_output_wrapper;    zuf.fopen_function = php_fopen_wrapper_for_zend;    zuf.message_handler = php_message_handler_for_zend;    zuf.block_interruptions = sapi_module.block_interruptions;    zuf.unblock_interruptions = sapi_module.unblock_interruptions;    zuf.get_configuration_directive = php_get_configuration_directive_for_zend;    zuf.ticks_function = php_run_ticks;    zuf.on_timeout = php_on_timeout;    zuf.stream_open_function = php_stream_open_for_zend;    zuf.vspprintf_function = vspprintf;    zuf.getenv_function = sapi_getenv;    zuf.resolve_path_function = php_resolve_path_for_zend;    zend_startup(&zuf, NULL TSRMLS_CC);

 

static int php_output_wrapper(const char *str, uint str_length){    TSRMLS_FETCH();    return php_output_write(str, str_length TSRMLS_CC);}PHPAPI int php_output_write(const char *str, size_t len TSRMLS_DC){    if (OG(flags) & PHP_OUTPUT_DISABLED) {        return 0;    }    if (OG(flags) & PHP_OUTPUT_ACTIVATED) {        php_output_op(PHP_OUTPUT_HANDLER_WRITE, str, len TSRMLS_CC);        return (int) len;    }    return php_output_direct(str, len);}static int (*php_output_direct)(const char *str, size_t str_len) = php_output_stderr;static int php_output_stderr(const char *str, size_t str_len){    fwrite(str, 1, str_len, stderr); //可知道echo 是用fwrite輸出的/* See http://support.microsoft.com/kb/190351 */#ifdef PHP_WIN32    fflush(stderr);#endif    return str_len;}

 

 參考:http://wenku.baidu.com/view/b7d2d4335a8102d276a22fb1.html

 

 

php-echo原理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.