在名稱空間提出之前,不同的元件很容易碰到命名的衝突,例如 Request 、Response 等常見的命名。PHP 在 5.3 後提出了名稱空間用來解決元件之間的命名衝突問題,主要參考了檔案系統的設計:
同一個目錄下不允許有相同的檔名 - 同一個名稱空間下不允許有相同的類;
不同的目錄可以有同名檔案 - 不同的名稱空間可以有相同的類;
定義
使用 namespace 關鍵字來定義一個名稱空間。其中,頂層名稱空間通常為廠商名,不同開發者的廠商名稱空間是唯一的。名稱空間不需要與檔案目錄一一對應,但是最好遵守 PSR-4 規範。
<?php namespace SymfonyComponentHttpFoundation; class Request { }
名稱空間必須在所有程式碼之前宣告,唯一的例外就是 declare 關鍵字。
<?php declare(strict_types=1); namespace App;
名稱空間內可包含任意 PHP 程式碼,但是僅對類 (包括抽象類和 Trait)、介面、函數和常數這四種型別生效。
<?php namespace MyProject; const CONNECT_OK = 1; class FOO {} interface Foo{} function foo() {}
使用
使用 use 關鍵字來引入名稱空間
<?php namespace App; use SymfonyComponentHttpFoundationRequest; use FooBar; class Test { public function run() { $bar = new Bar(); } }
定義和使用推薦遵循 PSR-2 的規範
namespace 之後必須存在一個空行;
所有 use 宣告必須位於 namespace 宣告之後;
每條 use 宣告必須只有一個 use 關鍵字。
use 語句塊之後必須存在一個空行。
當 use 引入的類出現同名時,可使用 as 來定義別名
<?php namespace App; use FooBar as BaseBar; class Bar extends BaseBar { }
限定符
除了使用 use 外,還可以直接使用 限定符來進行解析,規則很簡單:如果含有 字首則代表從全域性名稱空間開始解析,否則則代表從當前名稱空間開始解析。
<?php namespace App; FooBarfoo(); // 解析成 FooBarfoo(); FooBarfoo(); // 解析成 AppFooBarfoo();
此規則也適用於函數、常數等
$a = strlen('hi'); // 呼叫全域性函數 strlen $b = INI_ALL; // 存取全域性常數 INI_ALL $c = new Exception('error'); // 範例化全域性類 Exception
有兩個需要特別注意的地方:
對於函數和常數而言,如果當前名稱空間不存在,則會自動去全域性名稱空間去尋找,因此可省略 字首。對於類而言,如果當前名稱空間解析不到,不會去全域性空間尋找,因此,不可省略
$a = strlen('hi'); $b = INI_ALL; $c = new Exception('error'); // 錯誤 $c = new Exception('error'); // 正確
當動態呼叫名稱空間時,該名稱空間始終會被當成是全域性名稱空間,因此可以省略字首
$class1 = 'FooBar'; $object1 = new $class1; // 始終被解析成 FooBar
在內部存取名稱空間
PHP 支援兩種抽象的存取當前名稱空間內部元素的方法,__NAMESPACE__ 魔術常數和 namespace 關鍵字。
__NAMESPACE__ 常數的值是包含當前名稱空間名稱的字串,如果是在全域性名稱空間,則返回空字串。
<?php namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '' . $classname; return new $a; }
關鍵字 namespace 可用來顯式存取當前名稱空間或子名稱空間中的元素。它等價於類中的 self 操作符
namespace App; use blahblah as mine; blahmine(); // Appblahmine() namespaceblahmine(); // Appblahmine() namespacefunc(); // Appfunc() namespacesubfunc(); // Appsubfunc() namespacecname::method(); // Appcname::method() $a = new namespacesubcname(); // Appsubcname $b = namespaceCONSTANT; // AppCONSTANT
跳脫 符號
此外,推薦對所有的 進行跳脫,避免出現不可預期的後果
$class = "dangerousname"; // n 被解析成換行符 $obj = new $class; $class = 'dangerousname'; // 正確,但是不推薦 $class = 'dangerousname'; // 推薦 $class = "dangerousname"; // 推薦
以上就是PHP 核心特性之名稱空間的詳細內容,更多請關注TW511.COM其它相關文章!