<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在PHP中,用戶函數的定義從function關鍵字開始。如下所示簡單示例: function foo($var) { [echo](http://www.php.net/echo) $var; } 這是一個非常簡單的函數,它所實現的功能是定義一個函數,函數有一個參數,函數的內容是在標準輸出端輸出傳遞給它的參數變量的值。 函數的一切從function開始。我們從function開始函數定義的探索之旅。 **詞法分析** 在 Zend/zend_language_scanner.l中我們找到如下所示的代碼: <ST_IN_SCRIPTING>"function" { return T_FUNCTION; } 它所表示的含義是function將會生成T_FUNCTION標記。在獲取這個標記后,我們開始語法分析。 **語法分析** 在 Zend/zend_language_parser.y文件中找到函數的聲明過程標記如下: function: T_FUNCTION { $$.u.opline_num = CG(zend_lineno); } ; ? is_reference: /* empty */ { $$.op_type = ZEND_RETURN_VAL; } | '&' { $$.op_type = ZEND_RETURN_REF; } ; ? unticked_function_declaration_statement: function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); } '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); } ; > 關注點在 function is_reference T_STRING,表示function關鍵字,是否引用,函數名。 T_FUNCTION標記只是用來定位函數的聲明,表示這是一個函數,而更多的工作是與這個函數相關的東西,包括參數,返回值等。 **生成中間代碼** 語法解析后,我們看到所執行編譯函數為zend_do_begin_function_declaration。在 Zend/zend_complie.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) /* {{{ */ { ...//省略 function_token->u.op_array = CG(active_op_array); lcname = zend_str_tolower_dup(name, name_len); ? orig_interactive = CG(interactive); CG(interactive) = 0; init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); CG(interactive) = orig_interactive; ? ...//省略 ? if (is_method) { ...//省略 類方法 在后面的類章節介紹 } else { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); ? ? 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; 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)); } ? } /* }}} */ 生成的中間代碼為 **ZEND_DECLARE_FUNCTION** ,根據這個中間代碼及操作數對應的op_type。我們可以找到中間代碼的執行函數為 **ZEND_DECLARE_FUNCTION_SPEC_HANDLER**。 > 在生成中間代碼時,可以看到已經統一了函數名全部為小寫,表示函數的名稱不是區分大小寫的。 為驗證這個實現,我們看一段代碼: function T() { [echo](http://www.php.net/echo) 1; } ? function t() { [echo](http://www.php.net/echo) 2; } 執行代碼,可以看到屏幕上輸出如下報錯信息: Fatal error: Cannot redeclare t() (previously declared in ...) 表示對于PHP來說T和t是同一個函數名。檢驗函數名是否重復,這個過程是在哪進行的呢?下面將要介紹的函數聲明中間代碼的執行過程包含了這個檢查過程。 **執行中間代碼** 在 Zend/zend_vm_execute.h 文件中找到 ZEND_DECLARE_FUNCTION中間代碼對應的執行函數:ZEND_DECLARE_FUNCTION_SPEC_HANDLER。此函數只調用了函數do_bind_function。其調用代碼為: do_bind_function(EX(opline), EG(function_table), 0); 在這個函數中將EX(opline)所指向的函數添加到EG(function_table)中,并判斷是否已經存在相同名字的函數,如果存在則報錯。EG(function_table)用來存放執行過程中全部的函數信息,相當于函數的注冊表。它的結構是一個HashTable,所以在do_bind_function函數中添加新的函數使用的是HashTable的操作函數**zend_hash_add**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看