在討論如何使用命名空間之前,必須先了解 PHP 是如何知道要使用哪一個命名空間中的元素的。可以將 PHP 命名空間與檔案系統作一個簡單的類比。在檔案系統中存取一個檔案有三種方式:
相對檔案名稱形式如foo.txt。它會被解析為 currentdirectory/foo.txt,其中 currentdirectory 表示目前目錄。因此如果目前目錄是 /home/foo,則該檔名被解析為/home/foo/foo.txt。
相對路徑名形式如subdirectory/foo.txt。它會被解析為 currentdirectory/subdirectory/foo.txt。
絕對路徑名形式如/main/foo.txt。它會被解析為/main/foo.txt。
PHP 命名空間中的元素使用相同的原理。例如,類別名稱可以透過三種方式引用:
非限定名稱,或不包含前綴的類別名稱,例如 $a=new foo(); 或 foo::staticmethod();。如果目前命名空間是 currentnamespace,foo 將會解析為currentnamespacefoo。如果使用 foo 的程式碼是全域的,不包含在任何命名空間中的程式碼,則 foo 會被解析為foo。 警告:如果命名空間中的函數或常數未定義,則該非限定的函數名稱或常數名稱會被解析為全域函數名稱或常數名稱。
限定名稱,或包含前綴的名稱,例如 $a = new subnamespacefoo(); 或 subnamespacefoo::staticmethod();。如果目前的命名空間是 currentnamespace,則 foo 會解析為 currentnamespacesubnamespacefoo。如果使用 foo 的程式碼是全域性的,不包含在任何命名空間中的程式碼,foo 會被解析為subnamespacefoo。
完全限定名稱,或包含了全域前綴運算符的名稱,例如, $a = new currentnamespacefoo(); 或 currentnamespacefoo::staticmethod();。在這種情況下,foo 總是被解析為程式碼中的文字名稱(literal name)currentnamespacefoo。
下面是一個使用這三種方式的實例:
file1.php:
<?php namespace Foo\Bar\subnamespace; const FOO = 1; function foo() {} class foo { static function staticmethod() {} } ?>
file2.php:
<?php namespace Foo\Bar; include 'file1.php'; const FOO = 2; function foo() {} class foo { static function staticmethod() {} } /* 非限定名称 */ foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。 echo FOO; // resolves to constant Foo\Bar\FOO /* 限定名称 */ subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,以及类的方法 staticmethod echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO /* 完全限定名称 */ \Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo \Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO ?>
注意存取任意全域類別、函數或常數,都可以使用完全限定名稱,例如 strlen()或 Exception 或 INI_ALL。
Example #1 在命名空間內部存取全域類別、函數和常數
<?php namespace Foo; function strlen() {} const INI_ALL = 3; class Exception {} $a = \strlen('hi'); // 调用全局函数strlen $b = \INI_ALL; // 访问全局常量 INI_ALL $c = new \Exception('error'); // 实例化全局类 Exception ?>