<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 3.2.2 內部函數 上一節已經提過,內部函數指的是由內核、擴展提供的C語言編寫的function,這類函數不需要經歷opcode的編譯過程,所以效率上要高于PHP用戶自定義的函數,調用時與普通的C程序沒有差異。 Zend引擎中定義了很多內部函數供用戶在PHP中使用,比如:define、defined、strlen、method_exists、class_exists、function_exists......等等,除了Zend引擎中定義的內部函數,PHP擴展中也提供了大量內部函數,我們也可以靈活的通過擴展自行定制。 #### 3.2.2.1 內部函數結構 上一節介紹`zend_function`為union,其中`internal_function`就是內部函數用到的,具體結構: ```c //zend_complie.h typedef struct _zend_internal_function { /* Common elements */ zend_uchar type; zend_uchar arg_flags[3]; /* bitset of arg_info.pass_by_reference */ uint32_t fn_flags; zend_string* function_name; zend_class_entry *scope; zend_function *prototype; uint32_t num_args; uint32_t required_num_args; zend_internal_arg_info *arg_info; /* END of common elements */ void (*handler)(INTERNAL_FUNCTION_PARAMETERS); //函數指針,展開:void (*handler)(zend_execute_data *execute_data, zval *return_value) struct _zend_module_entry *module; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; } zend_internal_function; ``` `zend_internal_function`頭部是一個與`zend_op_array`完全相同的common結構。 下面看下如何定義一個內部函數。 #### 3.2.2.2 定義與注冊 內部函數與用戶自定義函數沖突,用戶無法在PHP代碼中覆蓋內部函數,執行PHP腳本時會提示error錯誤。 內部函數的定義非常簡單,我們只需要創建一個普通的C函數,然后創建一個`zend_internal_function`結構添加到 __EG(function_table)__ (也可能是CG(function_table),取決于在哪一階段注冊)中即可使用,內部函數 __通常__ 情況下是在php_module_startup階段注冊的,這里之所以說通常是按照標準的擴展定義,除了擴展提供的方式我們可以在任何階段自由定義內部函數,當然并不建議這樣做。下面我們先不討論擴展標準的定義方式,我們先自己嘗試下如何注冊一個內部函數。 根據`zend_internal_function`的結構我們知道需要定義一個handler: ```c void qp_test(INTERNAL_FUNCTION_PARAMETERS) { printf("call internal function 'qp_test'\n"); } ``` 然后創建一個內部函數結構(我們在擴展PHP_MINIT_FUNCTION方法中注冊,也可以在其他位置): ```c PHP_MINIT_FUNCTION(xxxxxx) { zend_string *lowercase_name; zend_function *reg_function; //函數名轉小寫,因為php的函數不區分大小寫 lowercase_name = zend_string_alloc(7, 1); zend_str_tolower_copy(ZSTR_VAL(lowercase_name), "qp_test", 7); lowercase_name = zend_new_interned_string(lowercase_name); reg_function = malloc(sizeof(zend_internal_function)); reg_function->internal_function.type = ZEND_INTERNAL_FUNCTION; //定義類型為內部函數 reg_function->internal_function.function_name = lowercase_name; reg_function->internal_function.handler = qp_test; zend_hash_add_ptr(CG(function_table), lowercase_name, reg_function); //注冊到CG(function_table)符號表中 } ``` 接著編譯、安裝擴展,測試: ```php qp_test(); ``` 結果輸出: `call internal function 'qp_test'` 這樣一個內部函數就定義完成了。這里有一個地方需要注意的我們把這個函數注冊到 __CG(function_table)__ 中去了,而不是 __EG(function_table)__ ,這是因為在`php_request_startup`階段會把 __CG(function_table)__ 賦值給 __EG(function_table)__ 。 上面的過程看著比較簡單,但是在實際應用中不要這樣做,PHP提供給我們一套標準的定義方式,接下來看下如何在擴展中按照官方方式提供一個內部函數。 首先也是定義C函數,這個通過`PHP_FUNCTION`宏定義: ```c PHP_FUNCTION(qp_test) { printf("call internal function 'qp_test'\n"); } ``` 然后是注冊過程,這個只需要我們將所有的函數數組添加到擴展結構`zend_module_entry.functions`即可,擴展加載過程中會自動進行函數注冊(見1.2節),不需要我們干預: ```c const zend_function_entry xxxx_functions[] = { PHP_FE(qp_test, NULL) PHP_FE_END }; zend_module_entry xxxx_module_entry = { STANDARD_MODULE_HEADER, "擴展名稱", xxxx_functions, PHP_MINIT(timeout), PHP_MSHUTDOWN(timeout), PHP_RINIT(timeout), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(timeout), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(timeout), PHP_TIMEOUT_VERSION, STANDARD_MODULE_PROPERTIES }; ``` 關于更多擴展中函數相關的用法會在后面擴展開發一章中詳細介紹,這里不再展開。
                  <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>

                              哎呀哎呀视频在线观看