WordPress 中的 PHP 命名空間——一本嚴肅的指南
已發表: 2018-10-16PHP 命名空間已經有將近十年的歷史了。 是的,十年過去了(是的,你變老了)。 儘管 PHP v5.3 發布已經過去了十年,但許多開發人員仍然對命名空間沒有基本的了解。 說實話WordPress 不使用命名空間,所以“如果你只使用 WordPress,你不需要知道如何使用命名空間。” 您不需要成為命名空間忍者,但掌握基礎知識很簡單,而且對您有好處。
PHP 命名空間已經存在了十年,您仍然不使用它們,因為#wordpress 也沒有? 閱讀並在 2 分鐘內開始使用它們! #發展
點擊推文當沒有命名空間支持時——使用前綴
很長很長一段時間以來,PHP 都沒有原生命名空間支持。 這就是 WordPress 和許多其他大型代碼庫不使用本機命名空間的原因。 它們在需要時不在身邊,因此使用了前綴。
命名空間很重要,因為它確保您的函數write_to_log()
尚未由另一段代碼定義。 為了避免名稱衝突,全局範圍內的所有內容都需要一個前綴,因此該函數變為awesome_project_write_to_log()
並且所有其他函數和變量也獲得了awesome_project_
前綴。 簡單的? 這是! 漂亮的? 不完全是。
該方法有一些替代方法,例如靜態方法封裝。 您將所有函數包裝在一個類中並將它們聲明為靜態方法。 然後調用My_Class::my_function()
而不是調用my_function()
() 。 更好的? 有點,但仍然不是正確的命名空間。
讓我們看看命名空間如何允許多個代碼段(或如果需要,可以使用包)使用相同的類和函數名而不會發生衝突。 或者正如 PHP 手冊所說——它們如何啟用代碼封裝。 它們與文件和文件夾的類比也很明顯——在很多方面命名空間的行為就像文件夾一樣,所以我將從手冊中復制/粘貼;
在任何操作系統中,目錄用於對相關文件進行分組並充當其中文件的命名空間。 例如,文件 foo.txt 可以同時存在於目錄 /home/greg 和 /home/other 中,但 foo.txt 的兩個副本不能共存於同一目錄中。 要訪問 /home/greg 目錄之外的 foo.txt 文件,我們必須使用目錄分隔符將完整目錄名添加到文件名前,以獲取 /home/greg/foo.txt。
聲明命名空間——記住第一行
關鍵字namespace
必須是文件中的第一行代碼(不包括註釋和任何非 PHP 內容)。 命名空間只影響類、接口、函數和常量。 它們不影響變量。 您可以在多個文件中定義相同的命名空間,從而允許您將代碼拆分為多個文件。 子命名空間允許在命名空間中定義層次結構,就像在文件夾中一樣,使用反斜杠namespace myproject\level1\level2
。 這些是聲明命名空間的基本規則和幾乎所有規則。
// file-A.php contains a function under the myCompany\PackageA namespace namespace myCompany\PackageA; function do_something() { // do things }
// file-B.php contains a function with the same name // but under a different namespace namespace myCompany\PackageB; function do_something() { // do things }
儘管可能,但我強烈建議不要將多個命名空間組合到一個文件中。 相信我,你遲早會忘記你做過,然後調試一個 2 分鐘的錯誤需要兩個小時。 但是,如果必須,這裡是語法。
// do not put multiple namespace declarations into the same file // but if you must, here's the syntax namespace MyFirstProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } namespace MySecondProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } // any code after this has to go in the global namespace namespace { $some_var = 1; function_in_global_namespace(); }
使用命名空間——記住文件夾
正如我已經說過的——命名空間與文件夾非常相似。 假設文件foo.txt
在您當前的文件夾中; 你可以用一個簡單的foo.txt
來引用它。 如果您比具有foo.txt
文件的文件夾高一級,則需要使用相對路徑../foo.txt
或絕對路徑/folder1/folder2/foo.txt
。 沒有什麼花哨。 命名空間使用相同的範例。
// remember after declaring a namespace // all our code is in it; like when you're working in a folder namespace mycompany\project; function foo() {} class foo { static function staticmethod() {} } // resolves to mycompany\project\foo() because of line #3 foo(); // likewise, resolves to mycompany\project\foo::staticmethod() foo::staticmethod(); // constant are affected by namespaces too // so we're working with mycompany\project\FOO echo FOO; // this is a relative path // resolves to mycompany\project\subnamespace\foo() subnamespace\foo(); // static methods are no different // mycompany\project\subnamespace\foo::staticmethod() subnamespace\foo::staticmethod(); // a full namespace path starts with a backslash // it resolves exactly to what it says it does \otherNamespace\Bar\foo(); // again same thing for a constant, full path nothing magical echo \otherNamespace\Bar\FOO;
看看 PHP 手冊中的use
關鍵字——例子很棒。 它提供了一種將代碼從其他 PHP 命名空間導入當前命名空間或使用別名引用外部(完全限定)名稱的方法。
是的,您需要命名空間並且應該使用它們
通過查看 WordPress 的源代碼,這一點非常明顯——您不必使用命名空間,但您必須使用一些命名空間的方法。 在 WP 的情況下以wp_
為前綴。 那麼,如果我們已經在做,為什麼不正確地做呢?
PHP 中的命名空間很容易集成到任何開發工作流程中。 它們簡化了自動加載、文件命名,並且通常使代碼更清晰。 重構舊代碼從來都不是一項流行的任務(不管編碼語言如何),所以我不會告訴您繼續重構一個工作的 2 MB 項目,以便您可以說您使用命名空間。 但是,我會堅持在處理新項目時使用命名空間。 你很快就會感謝自己的。
關於命名空間的官方 PHP 文檔非常棒! 代碼示例很乾淨,評論對現實世界很有幫助。 一定要瀏覽它,即使您認為不需要。