使用命名空間:基礎(chǔ)

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

在討論如何使用命名空間之前,必須了解 PHP 是如何知道要使用哪一個(gè)命名空間中的元素的??梢詫?PHP 命名空間與文件系統(tǒng)作一個(gè)簡單的類比。在文件系統(tǒng)中訪問一個(gè)文件有三種方式:

  1. 相對文件名形式如 foo.txt。它會被解析為 currentdirectory/foo.txt,其中 currentdirectory 表示當(dāng)前目錄。因此如果當(dāng)前目錄是 /home/foo,則該文件名被解析為 /home/foo/foo.txt。
  2. 相對路徑名形式如 subdirectory/foo.txt。它會被解析為 currentdirectory/subdirectory/foo.txt。
  3. 絕對路徑名形式如 /main/foo.txt。它會被解析為 /main/foo.txt。
PHP 命名空間中的元素使用同樣的原理。例如,類名可以通過三種方式引用:
  1. 非限定名稱,或不包含前綴的類名稱,例如 $a=new foo();foo::staticmethod();。如果當(dāng)前命名空間是 currentnamespace,foo 將被解析為 currentnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,則 foo 會被解析為 foo。 警告:如果命名空間中的函數(shù)或常量未定義,則該非限定的函數(shù)名稱或常量名稱會被解析為全局函數(shù)名稱或常量名稱。詳情參見 使用命名空間:后備全局函數(shù)名稱/常量名稱
  2. 限定名稱,或包含前綴的名稱,例如 $a = new subnamespace\foo();subnamespace\foo::staticmethod();。如果當(dāng)前的命名空間是 currentnamespace,則 foo 會被解析為 currentnamespace\subnamespace\foo。如果使用 foo 的代碼是全局的,不包含在任何命名空間中的代碼,foo 會被解析為 subnamespace\foo
  3. 完全限定名稱,或包含了全局前綴操作符的名稱,例如, $a = new \currentnamespace\foo();\currentnamespace\foo::staticmethod();。在這種情況下,foo 總是被解析為代碼中的文字名(literal name)currentnamespace\foo。

下面是一個(gè)使用這三種方式的實(shí)例:

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(); // 解析為函數(shù) Foo\Bar\foo 
foo::staticmethod(); // 解析為類 Foo\Bar\foo 的靜態(tài)方法 staticmethod
echo FOO// 解析為常量 Foo\Bar\FOO

/* 限定名稱 */
subnamespace\foo(); // 解析為函數(shù) Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析為類 Foo\Bar\subnamespace\foo,
                                  // 以及類的方法 staticmethod
echo subnamespace\FOO// 解析為常量 Foo\Bar\subnamespace\FOO
                                  
/* 完全限定名稱 */
\Foo\Bar\foo(); // 解析為函數(shù) Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析為類 Foo\Bar\foo, 以及類的方法 staticmethod
echo \Foo\Bar\FOO// 解析為常量 Foo\Bar\FOO
?>

注意訪問任意全局類、函數(shù)或常量,都可以使用完全限定名稱,例如 \strlen()\Exception\INI_ALL

示例 #1 在命名空間內(nèi)部訪問全局類、函數(shù)和常量

<?php
namespace Foo;

function 
strlen() {}
const 
INI_ALL 3;
class 
Exception {}

$a = \strlen('hi'); // 調(diào)用全局函數(shù)strlen
$b = \INI_ALL// 訪問全局常量 INI_ALL
$c = new \Exception('error'); // 實(shí)例化全局類 Exception
?>