超越前綴:PHP 命名空間的 WordPress 開發人員指南

已發表: 2019-11-12

前綴一切。

這是一句與 WordPress 軟件本身一樣古老的格言。 長期以來,前綴一直是 WordPress 開發人員的標準,以至於很難想像有什麼不同。 但是,是時候來點新東西了。 好吧,它早就過期了,但是 WordPress 在更大的 PHP 世界中的標準實踐有點落後。

前綴是創建項目名稱的代碼友好版本並將其粘貼到全局命名空間中的函數、類和其他事物的前面的做法。 例如,您將命名一個函數tavern_get_post()而不是get_post()以避免函數名稱衝突,這會導致致命錯誤。

前綴是“命名空間”的一種形式,它只是表示該空間中的名稱屬於特定項目的一種奇特方式。 然而,在 PHP 語言沒有解決方案的時候,前綴(和不太常見的後綴)是一種黑客行為。

PHP 5.3 引入了命名空間的官方方法,因此該標準已經存在多年。 因為 WordPress 5.2 將 PHP 的最低要求提高到了 5.6,所以現在是開發人員擺脫舊習慣並趕上 PHP 世界其他地方的時候了。

命名空間(幾乎)一切

PHP 命名空間僅涵蓋以下項目。

  • 課程
  • 接口
  • 性狀
  • 職能
  • 使用const關鍵字聲明但未使用define()的常量

當涉及到全局命名空間中的腳本句柄、圖像大小名稱、數據庫選項和其他項目時,您仍然必須為它們添加前綴。 這些是 ID,超出了 PHP 命名空間的範圍。

如何創建命名空間

命名空間很容易聲明。 在要使用特定命名空間的任何 PHP 文件的頂部,如以下代碼片段所示聲明它。

 <?php

命名空間酒館;

這行代碼的作用是聲明這個特定文件中的所有內容都具有Tavern的命名空間。

看一下該命名空間下的一個簡單函數,用於輸出Hello, World! 信息。

 <?php

命名空間酒館;

功能你好(){
    _e('Hello, World!', 'example-textdomain' );
}

如果遵循舊的前綴規則, hello()將被命名為tavern_hello() 。 但是,命名空間並非如此。 hello()函數封裝在Tavern命名空間中,不會與其他名為hello()的函數發生衝突。

類和接口與函數的工作方式相同。 類名稱為Article時,類文件可能如下所示。

 <?php

命名空間酒館;

類文章{
    // ...
}

注意:每個文件應該只有一個類或接口。 如果您打算使用自動裝載機,這一點尤其重要。

如何命名命名空間

開發人員喜歡爭論如何命名事物,並且沒有一刀切的解決方案。 最重要的規則是唯一的,以避免與其他項目的代碼發生衝突。 最好的方法之一是將頂級Vendor命名空間與Package子命名空間一起使用。

假設供應商命名空間是Tavern並且有問題的項目是一個名為News的 WordPress 主題。 項目的命名空間可能如下所示。

 <?php

命名空間酒館\新聞;

對於某些開發人員來說,這可能有點冗長。 如果您的項目名稱已經相當獨特,例如“Awesomesauce”,您可能只想使用以下名稱。

 <?php

命名空間 Awesomesauce;

您至少會想為自己制定某種標準約定。 最終,您會想要了解自動加載等內容,因此在您的所有項目中都遵循一個系統會有所幫助。 隨意閱讀 PHP-FIG Autoloader 標準。

將類和函數導入不同的命名空間

當您需要使用與當前命名空間不同的命名空間中的類或函數時,您需要導入它。 這是通過 PHP 中的use關鍵字完成的。

use語句必須在namespace聲明之後。 它還應該引用完全限定的類名。 以下代碼將Tavern\Helpers\Post類導入到具有不同命名空間的文件中。

 <?php

命名空間酒館\模板;

使用酒館\助手\郵政;

導入後,您可以安全地直接使用Post類,如下一個片段所示。

 $post = 新的帖子();

從 PHP 5.6 開始,您還可以分別使用use functionuse const關鍵字從其他命名空間導入函數和常量。 以下代碼塊演示瞭如何同時導入函數和常量。

 <?php

命名空間酒館\模板;

使用函數 Tavern\Helpers\func_name;
使用 const Tavern\Helpers\CONSTANT_NAME;

別名類和函數

最終,您將遇到需要導入與當前命名空間中的類或函數同名的類或函數的情況。 您可能會認為這是命名空間旨在解決的問題。 幸運的是,PHP 提供了一種在導入時創建別名的方法。

假設您有一個名為Tavern\User的類,並且需要實現Tavern\Contracts\User接口。 導入接口時,您需要創建一個別名,如下所示。

 <?php

命名空間酒館;

使用 Tavern\Contracts\User 作為 UserContract;

類用戶實現 UserContract {
    // ...
}

附加到use語句末尾的as UserContractUser界面創建了一個別名。 您可以安全地使用新的UserContract名稱而不會出錯。

類、接口、函數和常量都遵循相同的方法來創建別名。

基於命名空間組織文件夾結構

在更廣泛的 PHP 世界中,命名空間與項目的文件和文件夾結構相匹配是標準做法。 這樣做可以讓其他開發人員輕鬆地在您的項目中輕鬆定位代碼。 它還使得構建自動加載器以按需加載類變得簡單。

通常,所有 PHP 代碼都應該放在項目中的/src/inc或類似名稱的文件夾中。 示例插件文件和文件夾結構可能如下所示。

 /插件名稱
    /src
        /核
            /激活.php
            /Setup.php
        /看法
            /post.php
            /Page.php

如果遵循與命名空間相同的結構,則上述.php文件將包含以下類。

  • Tavern\Core\Activate
  • Tavern\Core\Setup
  • Tavern\View\Post
  • Tavern\View\Page

請注意,文件和文件夾名稱區分大小寫,並且應與命名空間和類名完全匹配。

當然,您可以自由地遵循您希望的任何約定。 但是,前面的建議是一種很好的做法,從長遠來看,它將簡化您組織項目的方式。

使用命名空間的好處

最明顯的好處是避免了同名的類和函數之間的衝突。 出於與使用前綴相同的原因,您應該使用真正的命名空間。

命名空間有助於避免長類名。 在整個大型項目中鍵入長名稱充其量是一種乏味的做法。

通過導入更輕鬆地切換實現。 一旦掌握了從其他命名空間導入類和接口的竅門,就可以用一行代碼切換接口的實現。

如果您遵循 PSR-4: Autoloader 標準,則自動加載類要容易得多,該標準至少需要一個頂級命名空間。

對於專業領域的開發人員,您將獲得 WordPress 生態系統之外的適銷對路的技能。 如果您不知道如何使用命名空間,您將很難找到 PHP 開發工作。 這不是一個很難掌握的概念,但在實踐中可能會有一些學習曲線。