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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                認識命名空間 ========== 理解命名空間 ----------- 在很久很久以前, PHP的世界大致上是這樣的: 啟動一個php腳本后, 一個個函數, 一個個類就被載入到同一個屋檐下, 開始按照你設計的邏輯一條條執行就夠了. 在這種情況下, 為了讓程序順利執行, 你必須確保一點: 同一個屋檐下的所有函數或者類必須有互不相同唯一的名字. 否則當出現重名時, php就不知道該執行哪個, 因此遇到這種情況, php必然會報錯終止. 在那時, 這確實很容易做到, 因為那時的php的項目都很單純, 很小, 沒有野心, 一個項目中的函數和類數量有限, 它們可以相對和諧地共同生活在同一個屋檐下. 但是, 隨著互聯網行業發展, 行業對Web項目的要求也在迅速提高: 一個PHP項目可能有數人甚至數十人共同開發, 項目需求龐大復雜. 產品更新迭代的需求越來越快. 這時, 在一個屋檐下容納所有的函數和類導致這個屋檐越來越擁擠, 難以管理. 當屋檐倒塌(需求出現重大變更), 也許埋葬的就是整個項目(代碼難以復用) . 這時, 一系列迫切需要解決的問題出現了: 1. 項目不同的部件之間如何避免出現函數和類名的沖突? 2. 項目越來越大, 命名時單詞似乎不夠用了, 如何讓函數和類命名時更容易? 3. 面對一大堆的函數和類, 如何有條理地管理它們的載入過程? 4. 面對快速變化的市場和需求, 項目必須模塊化, 易分割, 易替換, 可重用. 命名空間(namespace)為解決以上問題提供重要支撐. namespace 與邏輯無關, 它是一個管理概念, 通過命名空間你可以把函數和類管理的井井有條. 讓我們形象一點來闡述到底什么是"namespace". 中國有約70萬個行政村, 假如你的家鄉在"王村", 而中國叫"王村"的村子可能不下數百個. 而我想去訪問你的家鄉. 我該如何去? 你一定會這樣告訴我: **山西省 太原市 平遙縣 西六支鄉 王村**(假想地址). 如果王村就是一個class, 那么你正是通過namespace確保訪問到你的家鄉,而不是訪問另一個王村. 用程序語言的書寫習慣, 上面的地址可以換一種格式: **山西省\太原市\平遙縣\西六支鄉\王村** 好了, 中文太復雜, 讓我們換成拼音: **ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun**. 如果你初次接觸命名空間, 現在是不是有些恍然大悟, 原來這就是命名空間, 它可以讓我們輕松從70萬個村子(class)中精確找到自己真正要訪問的那個王村(class)而不會迷路. 使用命名空間 ---------- 在php中,聲明一個命名空間非常簡單,使用`namespace` 關鍵字: ``` namespace ShanXi\TaiYuan\PingYao\XiLiuZhi; ``` 在聲明了命名空間之后, **這條聲明之后直到下一條命名空間聲明之前**的所有函數,類,const常量就隸屬于這個命名空間了. ``` <?php namespace ShanXi\TaiYuan\PingYao\XiLiuZhi; const WangCun="I am WangCun."; function wang_cun(){ echo WangCun; } class WangCun { public function getName(){ wang_cun(); } } namespace ShanXi\TaiYuan\PingYao\Other; const WangCun="I am WangCun form Other."; function wang_cun(){ echo WangCun; } class WangCun { public function getName(){ wang_cun(); } } namespace Test; $obj1=new \ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun; $obj2=new \ShanXi\TaiYuan\PingYao\Other\WangCun; $obj1->getName(); // 輸出: "I am WangCun." $obj2->getName(); // 輸出: "I am WangCun from Other." ``` 通常一個php文件中只聲明一個命名空間, 為了解釋命名空間的用法和特性, 上面的示例, 我故意在同一個文件中聲明了三個命名空間. 如你所見, 我們在同一文件中似乎聲明了兩次名稱"相同的"const常量, 兩個名稱"相同的"函數, 兩個名稱"相同的"class. 它們可以和諧共處,不會產生沖突,因為它們位于不同的屋檐(namespace)下. 如果你足夠細心, 觀察上面的代碼你已經能夠知曉如何訪問命名空間下的成員: * 只要加上命名空間路徑, 就可以訪問其他命名空間的成員. * 如果沒有加命名空間路徑, PHP就將從當前命名空間下尋找成員. ### 一點疑惑 在上面的代碼中, 為什么使用的是: ``` $obj1=new \ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun; ``` 而不是 ``` $obj1=new ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun; ``` 這就像訪問目錄中的文件一樣, 如果你不加`\\`, php會認為你要訪問的是相對的命名空間, php會認為你想訪問的是`\Test\ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun` 深入命名空間 ------------ ### 全局命名空間 如果一個類或函數沒有定義在任何namespace之下, 那么它就屬于**全局命名空間**. 通常, 在一個命名空間下的代碼中訪問**類**或**const常量**時, php只會在當前命名空間下尋找. 如果未找到, 則會報錯,甚至退出. 不會進入全局空間搜索. 但對于函數訪問則特殊一點, 因為php是從函數式編程語言發展而來, 內置的數千函數現在都隸屬于了全局命名空間. 如果每次使用函數時, 都加上`\\`前綴無疑很容易讓人情緒崩潰. 因此, 如果在命名空間下沒有找到這個函數, php會試圖再去全局空間找一次. 在全局空間沒有找到才會報錯. * 有`\\`符號, 則表示絕對命名空間路徑. 沒有`\\`符號, 則表示相對命名空間路徑. * 全局空間習慣上也可以稱為"根空間" ### use 和 as 到現在, 我相信你已經理解并學會了命名空間的簡單使用. 讓我們繼續深入. 還是上面的示例代碼, 讓我們專注于 Test 命名空間: ``` namespace Test; $obj1=new \ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun; $obj2=new \ShanXi\TaiYuan\PingYao\Other\WangCun; $obj1->getName(); // 輸出: "I am WangCun." $obj2->getName(); // 輸出: "I am WangCun from Other." ``` 在訪問其他命名空間成員時, 我指定了完整路徑, 只訪問一個成員還說得過去, 如果訪問多個成員, 每次寫完整路徑豈不是很煩人? `use` 和 `as` 關鍵字解決你的煩惱, 下面是改造后的代碼示例: ``` namespace Test; use ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun as WangCun; use ShanXi\TaiYuan\PingYao\Other\WangCun as OtherWangCun; $obj1=new WangCun; $obj2=new OtherWangCun; $obj1->getName(); // 輸出: "I am WangCun." $obj2->getName(); // 輸出: "I am WangCun from Other." ``` 嗯, 終于可以少敲很多次鍵盤了. `use` 和 `as` 做了什么? * **use** 告訴php, 我要在Test命名空間下**直接**使用其他命名空間的某個類. * **as** 則告訴php這個其他命名空間的類在當前命名空間下使用什么名稱去訪問. * 當你不需要重新設定使用的名稱時, 而且不會引發重名問題時, **as** 可以省略 因此上面的代碼可以簡化為: ``` namespace Test; use ShanXi\TaiYuan\PingYao\XiLiuZhi\WangCun; use ShanXi\TaiYuan\PingYao\Other\WangCun as OtherWangCun; ... ``` ### 用namespace管理代碼載入 曽幾何時, php項目中到處充斥著include. 你必須時時小心以下問題: * 確保include的文件確實存在 * 確保include的文件的內容是你需要的 * 確保include的文件的內容不與以有代碼產生沖突 * 每次修改include的文件, 都要小心翼翼確保不會產生沖突 * 在一個被include的文件刪除后, 你必須在所有代碼中搜索一遍, 刪除每一處include * include時還需要特別留意工作目錄和相對路徑的問題. 對程序員來說, 這簡直一場噩夢. 因為它們與邏輯幾乎毫無關系, 卻需要耗費你大量的時間心血去處理, 最重要的是, 這些問題真的太太傷感情了, 很容易讓你懷疑自己選擇程序員是否是個正確的決定. namespace 助你解脫. namespace 為你的代碼帶來了分明的層次感, 它幾乎就是我們電腦上目錄結構的翻版. 你的電腦上文件目錄再多, 我相信你也能輕松找到那個自己密不外宣的特殊目錄. 你越悉心管理自己的電腦目錄, 你使用電腦的工作效率就越高,出錯概率越低. 所以, 你的php項目的 namespace 規劃的越合理, 越層次分明, 你的項目就會越容易維護. 如果我們把命名空間與文件系統上的層次結構對應起來, 自動載入就成為了現實, include就成為了歷史: 目錄結構: ``` .\ShanXi |- TaiYuan |- PingYao |- XiLiuZhi | |- WangCun.php | |- Other |- WangCun.php ``` 現在你只需要定義一個自動載入函數注冊到autload函數棧, 為命名空間路徑和本地路徑的關系建立邏輯, 根據這個固定的邏輯, 就可以自動載入任何的符合該邏輯的類了! 最重要的是: 1. 自定義的自動載入函數可以注冊許多個, 意味著你可以設計多種自動載入邏輯. 在訪問類時, php會根據注冊時的順序, 依次執行, 直到找到需要載入的文件為止. 2. 只有在第一次訪問類時, 才會觸發自動載入, 如果一個類沒有用到, 那么這個類文件也就不會被載入. 在你設計好自動加載函數后, 調用`spl_autoload_register($callable)` 即可將你的自動加載器注冊到php的autoload棧中. 所有使用了命名空間的現代的PHP項目和框架, 都是使用這種機制實現了類文件的自動加載. 你只需要按照規則放置類文件, 就可以隨處使用它們. 介紹到這里, 你對命名空間的了解已經足夠多. 如果還想徹底精通, 可以訪問PHP文檔中命名空間部分: <http://php.net/manual/zh/language.namespaces.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>

                              哎呀哎呀视频在线观看