<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 命名空間概述[]() 在維基百科中,對[命名空間](http://zh.wikipedia.org/wiki/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4)的定義是:命名空間(英語:Namespace)表示標識符(identifier)的上下文(context)。一個標識符可在多個命名空間中定義,它在不同命名空間中的含義是互不相干的。在編程語言中,命名空間是一種特殊的作用域,它包含了處于該作用域內的標識符,且本身也用一個標識符來表示,這樣便將一系列在邏輯上相關的標識符用一個標識符組織了起來。函數和類的作用域可被視作隱式命名空間,它們和可見性、可訪問性和對象生命周期不可分割的聯系在一起。 命名空間可以看作是一種封裝事物的方法,同時也可以看作是組織代碼結構的一種形式,在很多語言中都可以見到這種抽象概念和組織形式。在PHP中,命名空間用來解決在編寫類庫或應用程序時創建可重用的代碼如類或函數時碰到的兩類問題: 1. 用戶編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字沖突。 1. 為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,提高源代碼的可讀性。 PHP從5.3.0版本開始支持命名空間特性。看一個定義和使用命名空間的示例: <?php namespace tipi; class Exception { public [static](http://www.php.net/static) $var = 'think in php internal'; } ? const E_ALL = "E_ALL IN Tipi"; ? function [strlen](http://www.php.net/strlen)(){ [echo](http://www.php.net/echo) 'strlen in tipi'; } ? [echo](http://www.php.net/echo) Exception::$var; [echo](http://www.php.net/echo) [strlen](http://www.php.net/strlen)(Exception::$var); 如上所示,定義了命名空間tipi,在這個命名空間內定義了一個Exception類,一個E_ALL常量和一個函數strlen。這些類、常量和函數PHP默認已經實現。假如沒有這個命名空間,聲明這些類、常量或函數時會報函數重復聲明或類重復聲明的錯誤,并且常量的定義也不會成功。 從PHP語言來看,命名空間通過 **namespace** 關鍵字定義,在命名空間內,可以包括任何合法的PHP代碼,但是它的影響范圍僅限于類、常量和函數。從語法上來講,PHP支持在一個文件中定義多個命名空間,但是不推薦這種代碼組織方式。當需要將全局的非命名空間中的代碼與命名空間中的代碼組合在一起,全局代碼必須用一個不帶名稱的 namespace 語句加上大括號括起來。 此時,思考一下,在PHP內核中,命名空間的定義是如何實現的呢?當在多個命名空間中存在多個相同的函數或類時,如何區分?命名空間內的函數如何調用? ## 命名空間的定義[]() 命名空間在PHP中的實現方案比較簡單,不管是函數,類或者常量,在聲明的過程中都將命名空間與定義的函數名以\合并起來,作為函數名或類名存儲在其對應的容器中。如上面示例中的Exception類,最后存儲的類名是tipi\Exception。對于整個PHP實現的架構來說,這種實現方案的代價和對整個代碼結構的調整都是最小的。 下面我們以Exception類為例說明整個命名空間的實現。命名空間實現的關鍵字是namespace,從此關鍵字開始我們可以找到在編譯時處理此關鍵字的函數為 **zend_do_begin_namespace**。在此函數中,關鍵是在對CG(current_namespace)的賦值操作,這個值在后面類聲明或函數等聲明時都會有用到。 在前面我們講過,類聲明的實現在編譯時會調用Zend/zend_complie.c文件中的zend_do_begin_class_declaration函數,在此函數中對于命名空間的處理代碼如下: if (CG(current_namespace)) { /* Prefix class name with name of current namespace */ znode tmp; ? tmp.u.constant = *CG(current_namespace); zval_copy_ctor(&tmp.u.constant); zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC); class_name = &tmp; efree(lcname); lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant)); } 這段代碼的作用是如果當前存在命名空間,則給類名加上命名空間的前綴,如前面提到示例中的tipi\Exception類,添加tipi\的操作就是在這里執行的。在zend_do_build_namespace_name函數中最終會調用zend_do_build_full_name函數實現類名的合并。在函數和常量的聲明中存在同樣的名稱合并操作。這也是命名空間僅對類、常量和函數有效的原因。 ## 使用命名空間[]() 以函數調用為例,當需要調用函數時,會調用zend_do_begin_function_call函數。在此函數中,當使用到命名空間時會檢查函數名,其調用的函數為zend_resolve_non_class_name。在zend_resolve_non_class_name函數中會根據類型作出判斷并返回相關結果: 1. 完全限定名稱的函數:程序首先會做此判斷,其判斷的依據是第一個字符是否為"\",這種情況下,在解析時會直接返回。如類似于\strlen這樣以\開頭的全局調用或類似于前面定義的\tipi\Exception調用。 1. 所有的非限定名稱和限定名稱(非完全限定名稱):根據當前的導入規則程序判斷是否為別名,并從編譯期間存儲別名的HashTable中取出對應的命名空間名稱,將其與現有的函數名合并。關于別名的存儲及生成在后面的內容中會說明, 1. 在命名空間內部:所有的沒有根據導入規則轉換的限定名稱均會在其前面加上當前的命名空間名稱。最后判斷是否在當前命名空間,最終程序都會返回一個合并了命名空間的函數名。 ### 別名/導入[]() 允許通過別名引用或導入外部的完全限定名稱,是命名空間的一個重要特征。這有點類似于在類 unix 文件系統中可以創建對其它的文件或目錄的符號連接。PHP 命名空間支持 有兩種使用別名或導入方式:為類名稱使用別名,或為命名空間名稱使用別名。 > PHP不支持導入函數或常量 在PHP中,別名是通過操作符 use 來實現的。從而我們可以從源碼中找到編譯時調用的函數是zend_do_use。別名在編譯為中間代碼過程中存放在CG(current_import)中,這是一個HashTable。zend_do_use整個函數的實現基本上是一個查找,判斷是否錯誤,最后寫入到HashTable的過程。其中針對命名空間和類名都有導入的處理過程,而對于常量和函數來說卻沒有,這就是PHP不支持導入函數或常量的根本原因所在。
                  <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>

                              哎呀哎呀视频在线观看