<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之旅 廣告
                ### 3.4.6 類的自動加載 在實際使用中,通常會把一個類定義在一個文件中,然后使用時include加載進來,這樣就帶來一個問題:在每個文件的頭部都需要包含一個長長的include列表,而且當文件名稱修改時也需要把每個引用的地方都改一遍,另外前面我們也介紹過,原則上父類需要在子類定義之前定義,當存在大量類時很難得到保證,因此PHP提供了一種類的自動加載機制,當使用未被定義的類時自動調用類加載器將類加載進來,方便類的同一管理。 在內核實現上類的自動加載實際就是定義了一個鉤子函數,實例化類時如果在EG(class_table)中沒有找到對應的類則會調用這個鉤子函數,調用完以后再重新查找一次。這個鉤子函數保存在EG(autoload_func)中。 PHP中提供了兩種方式實現自動加載:`__autoload()`、`spl_autoload_register()`。 ***(1)__autoload():*** 這種方式比較簡單,用戶自定義一個`__autoload()`函數即可,參數是類名,當實例化一個類是如果沒有找到這個類則會查找用戶是否定義了`__autoload()`函數,如果定義了則調用此函數,比如: ```php //文件1:my_class.php <?php class my_class { public $id = 123; } //文件2:b.php <?php function __autoload($class_name){ //do something... include $class_name . '.php'; } $obj = new my_class(); var_dump($obj); ``` __(2)spl_autoload_register():__ 相比`__autoload()`只能定義一個加載器,`spl_autoload_register()`提供了更加靈活的注冊方式,可以支持任意數量的加載器,比如第三方庫加載規則不可能保持一致,這樣就可以通過此函數注冊自己的加載器了,在實現上spl創建了一個隊列來保存用戶注冊的加載器,然后定義了一個spl_autoload函數到EG(autoload_func),當找不到類時內核回調spl_autoload,這個函數再依次調用用戶注冊的加載器,沒調用一個重新檢查下查找的類是否在EG(class_table)中已經注冊,仍找不到的話繼續調用下一個加載器,直到類成功注冊為止。 ```c bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] ) ``` 參數`$autoload_function`為加載器,可以是函數名,第2個參數`$throw`用于設置autoload_function 無法成功注冊時, spl_autoload_register()是否拋出異常,最后一個參數如果為true時spl_autoload_register() 會添加函數到隊列之首,而不是隊列尾部。 ```php function autoload_one($class_name){ echo "autoload_one->", $class_name, "\n"; } function autoload_two($class_name){ echo "autoload_two->", $class_name, "\n"; } spl_autoload_register("autoload_one"); spl_autoload_register("autoload_two"); $obj = new my_class(); var_dump($obj); ``` 這個例子執行時就會將autoload_one()、autoload_two()都調一遍,假如第一個函數就成功注冊了my_class類則不會再調后面的加載器。 內核查找類通過`zend_lookup_class_ex()`完成,我們簡單看下其處理過程。 ```c //file: zend_execute_API.c ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload) { ... //從EG(class_table)符號表找類的zend_class_entry,如果找到說明類已經編譯,直接返回 ce = zend_hash_find_ptr(EG(class_table), lc_name); if (ce) { if (!key) { zend_string_release(lc_name); } return ce; } ... //如果沒有通過spl注冊則看下是否定義了__autoload() if (!EG(autoload_func)) { zend_function *func = zend_hash_str_find_ptr(EG(function_table), "__autoload", sizeof("__autoload") - 1); if (func) { EG(autoload_func) = func; } else { return NULL; } } ... fcall_cache.function_handler = EG(autoload_func); ... //調用EG(autoload_func)函數,然后再查一次EG(class_table) if ((zend_call_function(&fcall_info, &fcall_cache) == SUCCESS) && !EG(exception)) { ce = zend_hash_find_ptr(EG(class_table), lc_name); } ... } ``` SPL的具體實現比較簡單,這里不再介紹。
                  <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>

                              哎呀哎呀视频在线观看