PHP 命名空间(namespace)是在PHP 5.3中加入的,如果你学过C#和Java,那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。
PHP 命名空间可以解决以下两类问题:
默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。
命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。语法格式如下;
php <span style="color: #008000;">//</span><span style="color: #008000;"> 定义代码在 'MyProject' 命名空间中 </span> <span style="color: #000000;">namespace MyProject; </span><span style="color: #008000;">//</span><span style="color: #008000;"> ... 代码 ... </span>
<span class="pln"> </span>
你也可以在同一个文件中定义不同的命名空间代码,如:
php namespace MyProject1; <span style="color: #008000;">//</span><span style="color: #008000;"> MyProject1 命名空间中的PHP代码 </span> <span style="color: #000000;"> namespace MyProject2; </span><span style="color: #008000;">//</span><span style="color: #008000;"> MyProject2 命名空间中的PHP代码 // 另一种语法</span> <span style="color: #000000;">namespace MyProject3 { </span><span style="color: #008000;">//</span><span style="color: #008000;"> MyProject3 命名空间中的PHP代码 </span> <span style="color: #000000;">} </span>?>
在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。
<span style="color: #000000;">php </span><span style="color: #0000ff;">declare</span>(encoding='UTF-8'); <span style="color: #008000;">//</span><span style="color: #008000;">定义多个命名空间和不包含在命名空间中的代码</span> <span style="color: #000000;">namespace MyProject { </span><span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } } namespace { </span><span style="color: #008000;">//</span><span style="color: #008000;"> 全局代码</span> <span style="color: #008080;">session_start</span><span style="color: #000000;">(); </span><span style="color: #800080;">$a</span> =<span style="color: #000000;"> MyProject\connect(); </span><span style="color: #0000ff;">echo</span> MyProject\Connection::<span style="color: #000000;">start(); } </span>?>
以下代码会出现语法错误:
<span style="color: #000000;">php namespace MyProject; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 命名空间前出现了“” 会致命错误 - 命名空间必须是程序脚本的第一条语句</span> ?>
与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义:
<span style="color: #000000;">php namespace MyProject\Sub\Level; </span><span style="color: #008000;">//</span><span style="color: #008000;">声明分层次的单个命名空间</span> <span style="color: #0000ff;">const</span> CONNECT_OK = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> Connection { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span><span style="color: #0000ff;">function</span> Connect() { <span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span><span style="color: #000000;"> } </span>?>
<span class="pun"> </span>
上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。
PHP 命名空间中的类名可以通过三种方式引用:
下面是一个使用这三种方式的实例:
file1.php 文件代码
<span style="color: #000000;">php namespace Foo\Bar\subnamespace; </span><span style="color: #0000ff;">const</span> FOO = 1<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> foo() {} </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> foo { </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> staticmethod() {} } </span>?>
<span class="pun"> </span>
file2.php 文件代码
<span style="color: #000000;">php namespace Foo\Bar; </span><span style="color: #0000ff;">include</span> 'file1.php'<span style="color: #000000;">; </span><span style="color: #0000ff;">const</span> FOO = 2<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> foo() {} </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> foo { </span><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> staticmethod() {} } </span><span style="color: #008000;">/*</span><span style="color: #008000;"> 非限定名称 </span><span style="color: #008000;">*/</span><span style="color: #000000;"> foo(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo</span> foo::staticmethod(); <span style="color: #008000;">//</span><span style="color: #008000;"> 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod</span> <span style="color: #0000ff;">echo</span> FOO; <span style="color: #008000;">//</span><span style="color: #008000;"> resolves to constant Foo\Bar\FOO</span> <span style="color: #008000;">/*</span><span style="color: #008000;"> 限定名称 </span><span style="color: #008000;">*/</span><span style="color: #000000;"> subnamespace\foo(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析为函数 Foo\Bar\subnamespace\foo</span> subnamespace\foo::staticmethod(); <span style="color: #008000;">//</span><span style="color: #008000;"> 解析为类 Foo\Bar\subnamespace\foo, // 以及类的方法 staticmethod</span> <span style="color: #0000ff;">echo</span> subnamespace\FOO; <span style="color: #008000;">//</span><span style="color: #008000;"> 解析为常量 Foo\Bar\subnamespace\FOO</span> <span style="color: #008000;">/*</span><span style="color: #008000;"> 完全限定名称 </span><span style="color: #008000;">*/</span><span style="color: #000000;"> \Foo\Bar\foo(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> 解析为函数 Foo\Bar\foo</span> \Foo\Bar\foo::staticmethod(); <span style="color: #008000;">//</span><span style="color: #008000;"> 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod</span> <span style="color: #0000ff;">echo</span> \Foo\Bar\FOO; <span style="color: #008000;">//</span><span style="color: #008000;"> 解析为常量 Foo\Bar\FOO</span> ?>
<span class="pun"> </span>
注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。
在命名空间内部访问全局类、函数和常量:
<span style="color: #000000;">php namespace Foo; </span><span style="color: #0000ff;">function</span> <span style="color: #008080;">strlen</span><span style="color: #000000;">() {} </span><span style="color: #0000ff;">const</span> INI_ALL = 3<span style="color: #000000;">; </span><span style="color: #0000ff;">class</span> <span style="color: #0000ff;">Exception</span><span style="color: #000000;"> {} </span><span style="color: #800080;">$a</span> = \<span style="color: #008080;">strlen</span>('hi'); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局函数strlen</span> <span style="color: #800080;">$b</span> = \INI_ALL; <span style="color: #008000;">//</span><span style="color: #008000;"> 访问全局常量 INI_ALL</span> <span style="color: #800080;">$c</span> = <span style="color: #0000ff;">new</span> \<span style="color: #0000ff;">Exception</span>('error'); <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化全局类 Exception</span> ?>
<span class="pun"> </span>
PHP 命名空间的实现受到其语言自身的动态特征的影响。因此,如果要将下面的代码转换到命名空间中,动态访问元素。
example1.php 文件代码:
<span style="color: #000000;">php </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> classname { </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> __construct() { </span><span style="color: #0000ff;">echo</span> <span style="color: #ff00ff;">__METHOD__</span>,"\n"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> funcname() { </span><span style="color: #0000ff;">echo</span> <span style="color: #ff00ff;">__FUNCTION__</span>,"\n"<span style="color: #000000;">; } </span><span style="color: #0000ff;">const</span> constname = "global"<span style="color: #000000;">; </span><span style="color: #800080;">$a</span> = 'classname'<span style="color: #000000;">; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> prints classname::__construct</span> <span style="color: #800080;">$b</span> = 'funcname'<span style="color: #000000;">; </span><span style="color: #800080;">$b</span>(); <span style="color: #008000;">//</span><span style="color: #008000;"> prints funcname</span> <span style="color: #0000ff;">echo</span> <span style="color: #008080;">constant</span>('constname'), "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> prints global</span> ?>
<span class="pun"> </span>
必须使用完全限定名称(包括命名空间前缀的类名称)。注意因为在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的。
动态访问命名空间的元素
<span style="color: #000000;">php namespace namespacename; </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> classname { </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> __construct() { </span><span style="color: #0000ff;">echo</span> <span style="color: #ff00ff;">__METHOD__</span>,"\n"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> funcname() { </span><span style="color: #0000ff;">echo</span> <span style="color: #ff00ff;">__FUNCTION__</span>,"\n"<span style="color: #000000;">; } </span><span style="color: #0000ff;">const</span> constname = "namespaced"<span style="color: #000000;">; </span><span style="color: #0000ff;">include</span> 'example1.php'<span style="color: #000000;">; </span><span style="color: #800080;">$a</span> = 'classname'<span style="color: #000000;">; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> prints classname::__construct</span> <span style="color: #800080;">$b</span> = 'funcname'<span style="color: #000000;">; </span><span style="color: #800080;">$b</span>(); <span style="color: #008000;">//</span><span style="color: #008000;"> prints funcname</span> <span style="color: #0000ff;">echo</span> <span style="color: #008080;">constant</span>('constname'), "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> prints global</span> <span style="color: #008000;">/*</span><span style="color: #008000;"> note that if using double quotes, "\\namespacename\\classname" must be used </span><span style="color: #008000;">*/</span> <span style="color: #800080;">$a</span> = '\namespacename\classname'<span style="color: #000000;">; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> prints namespacename\classname::__construct</span> <span style="color: #800080;">$a</span> = 'namespacename\classname'<span style="color: #000000;">; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> also prints namespacename\classname::__construct</span> <span style="color: #800080;">$b</span> = 'namespacename\funcname'<span style="color: #000000;">; </span><span style="color: #800080;">$b</span>(); <span style="color: #008000;">//</span><span style="color: #008000;"> prints namespacename\funcname</span> <span style="color: #800080;">$b</span> = '\namespacename\funcname'<span style="color: #000000;">; </span><span style="color: #800080;">$b</span>(); <span style="color: #008000;">//</span><span style="color: #008000;"> also prints namespacename\funcname</span> <span style="color: #0000ff;">echo</span> <span style="color: #008080;">constant</span>('\namespacename\constname'), "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> prints namespaced</span> <span style="color: #0000ff;">echo</span> <span style="color: #008080;">constant</span>('namespacename\constname'), "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> also prints namespaced</span> ?>
<span class="pun"> </span>
PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和namespace关键字。
常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。
__NAMESPACE__ 示例, 在命名空间中的代码
<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">echo</span> '"', __NAMESPACE__, '"'; <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 "MyProject"</span> ?>
<span class="pun"> </span>
__NAMESPACE__ 示例,全局代码
<span style="color: #000000;">php </span><span style="color: #0000ff;">echo</span> '"', __NAMESPACE__, '"'; <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 ""</span> ?>
<span class="pun"> </span>
常量 __NAMESPACE__ 在动态创建名称时很有用,例如:
使用__NAMESPACE__动态创建名称
<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">function</span> get(<span style="color: #800080;">$classname</span><span style="color: #000000;">) { </span><span style="color: #800080;">$a</span> = __NAMESPACE__ . '\\' . <span style="color: #800080;">$classname</span><span style="color: #000000;">; </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span><span style="color: #000000;">; } </span>?>
<span class="pun"> </span>
关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。
namespace操作符,命名空间中的代码
<span style="color: #000000;">php namespace MyProject; </span><span style="color: #0000ff;">use</span> blah\blah <span style="color: #0000ff;">as</span> mine; <span style="color: #008000;">//</span><span style="color: #008000;"> see "Using namespaces: importing/aliasing"</span> <span style="color: #000000;"> blah\mine(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> calls function blah\blah\mine()</span> namespace\blah\mine(); <span style="color: #008000;">//</span><span style="color: #008000;"> calls function MyProject\blah\mine()</span> <span style="color: #000000;"> namespace\func(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> calls function MyProject\func()</span> namespace\sub\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> calls function MyProject\sub\func()</span> namespace\cname::method(); <span style="color: #008000;">//</span><span style="color: #008000;"> calls static method "method" of class MyProject\cname</span> <span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> namespace\sub\cname(); <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class MyProject\sub\cname</span> <span style="color: #800080;">$b</span> = namespace\<span style="color: #008080;">CONSTANT</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> assigns value of constant MyProject\CONSTANT to $b</span> ?>
<span class="pun"> </span>
namespace操作符, 全局代码
<span style="color: #000000;">php namespace\func(); </span><span style="color: #008000;">//</span><span style="color: #008000;"> calls function func()</span> namespace\sub\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> calls function sub\func()</span> namespace\cname::method(); <span style="color: #008000;">//</span><span style="color: #008000;"> calls static method "method" of class cname</span> <span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> namespace\sub\cname(); <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class sub\cname</span> <span style="color: #800080;">$b</span> = namespace\<span style="color: #008080;">CONSTANT</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> assigns value of constant CONSTANT to $b</span> ?>
<span class="pun"> </span>
PHP 命名空间支持 有两种使用别名或导入方式:为类名称使用别名,或为命名空间名称使用别名。注意PHP不支持导入函数或常量。
在PHP中,别名是通过操作符 use 来实现的. 下面是一个使用所有可能的三种导入方式的例子:
1、使用use操作符导入/使用别名
<span style="color: #000000;">php namespace foo; </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span><span style="color: #000000;"> Another; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 下面的例子与 use My\Full\NSname as NSname 相同</span> <span style="color: #0000ff;">use</span><span style="color: #000000;"> My\Full\NSname; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 导入一个全局类</span> <span style="color: #0000ff;">use</span><span style="color: #000000;"> \ArrayObject; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> namespace\Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 foo\Another 对象</span> <span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 My\Full\Classname 对象</span> NSname\subns\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用函数 My\Full\NSname\subns\func</span> <span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> ArrayObject(<span style="color: #0000ff;">array</span>(1)); <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 ArrayObject 对象 // 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象</span> ?>
<span class="pun"> </span>
2、 一行中包含多个use语句
<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span> Another,<span style="color: #000000;"> My\Full\NSname; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化 My\Full\Classname 对象</span> NSname\subns\func(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用函数 My\Full\NSname\subns\func</span> ?>
<span class="pun"> </span>
导入操作是在编译执行的,但动态的类名称、函数名称或常量名称则不是。
3、导入和动态名称
<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span> Another,<span style="color: #000000;"> My\Full\NSname; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> 实例化一个 My\Full\Classname 对象</span> <span style="color: #800080;">$a</span> = 'Another'<span style="color: #000000;">; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> <span style="color: #800080;">$a</span>; <span style="color: #008000;">//</span><span style="color: #008000;"> 实际化一个 Another 对象</span> ?>
另外,导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的,故不受导入的影响。
4、导入和完全限定名称
<span style="color: #000000;">php </span><span style="color: #0000ff;">use</span> My\Full\Classname <span style="color: #0000ff;">as</span> Another,<span style="color: #000000;"> My\Full\NSname; </span><span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another; <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class My\Full\Classname</span> <span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> \Another; <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class Another</span> <span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> Another\thing; <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class My\Full\Classname\thing</span> <span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span> \Another\thing; <span style="color: #008000;">//</span><span style="color: #008000;"> instantiates object of class Another\thing</span> ?>
在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称,例如:
1、在命名空间中访问全局类
<span style="color: #000000;">php namespace A\B\C; </span><span style="color: #0000ff;">class</span> <span style="color: #0000ff;">Exception</span> <span style="color: #0000ff;">extends</span> \<span style="color: #0000ff;">Exception</span><span style="color: #000000;"> {} </span><span style="color: #800080;">$a</span> = <span style="color: #0000ff;">new</span> <span style="color: #0000ff;">Exception</span>('hi'); <span style="color: #008000;">//</span><span style="color: #008000;"> $a 是类 A\B\C\Exception 的一个对象</span> <span style="color: #800080;">$b</span> = <span style="color: #0000ff;">new</span> \<span style="color: #0000ff;">Exception</span>('hi'); <span style="color: #008000;">//</span><span style="color: #008000;"> $b 是类 Exception 的一个对象</span> <span style="color: #800080;">$c</span> = <span style="color: #0000ff;">new</span> ArrayObject; <span style="color: #008000;">//</span><span style="color: #008000;"> 致命错误, 找不到 A\B\C\ArrayObject 类</span> ?>
<span class="pun"> </span>
对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。
2、 命名空间中后备的全局函数/常量
<span style="color: #000000;">php namespace A\B\C; </span><span style="color: #0000ff;">const</span> <span style="color: #ff00ff;">E_ERROR</span> = 45<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span> <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$str</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">return</span> \<span style="color: #008080;">strlen</span>(<span style="color: #800080;">$str</span>) - 1<span style="color: #000000;">; } </span><span style="color: #0000ff;">echo</span> <span style="color: #ff00ff;">E_ERROR</span>, "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 "45"</span> <span style="color: #0000ff;">echo</span> INI_ALL, "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 "7" - 使用全局常量 INI_ALL</span> <span style="color: #0000ff;">echo</span> <span style="color: #008080;">strlen</span>('hi'), "\n"; <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 "1"</span> <span style="color: #0000ff;">if</span> (<span style="color: #008080;">is_array</span>('hi')) { <span style="color: #008000;">//</span><span style="color: #008000;"> 输出 "is not array"</span> <span style="color: #0000ff;">echo</span> "is array\n"<span style="color: #000000;">; } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">echo</span> "is not array\n"<span style="color: #000000;">; } </span>?>
<span class="pun"> </span>
如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称,即使该名称位于其它的命名空间中时也是如此。
使用全局空间说明
<span style="color: #000000;">php namespace A\B\C; </span><span style="color: #008000;">/*</span><span style="color: #008000;"> 这个函数是 A\B\C\fopen </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">function</span> <span style="color: #008080;">fopen</span><span style="color: #000000;">() { </span><span style="color: #008000;">/*</span><span style="color: #008000;"> ... </span><span style="color: #008000;">*/</span> <span style="color: #800080;">$f</span> = \<span style="color: #008080;">fopen</span>(...); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局的fopen函数</span> <span style="color: #0000ff;">return</span> <span style="color: #800080;">$f</span><span style="color: #000000;">; } </span>?>
<span class="pun"> </span>
自从有了命名空间之后,最容易出错的该是使用类的时候,这个类的寻找路径是什么样的了。
<span style="color: #008080;"> 1</span> <span style="color: #000000;">php </span><span style="color: #008080;"> 2</span> <span style="color: #000000;">namespace A; </span><span style="color: #008080;"> 3</span> <span style="color: #0000ff;">use</span> B\D, C\E <span style="color: #0000ff;">as</span><span style="color: #000000;"> F; </span><span style="color: #008080;"> 4</span> <span style="color: #008080;"> 5</span> <span style="color: #008000;">//</span><span style="color: #008000;"> 函数调用</span> <span style="color: #008080;"> 6</span> <span style="color: #008080;"> 7</span> foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 首先尝试调用定义在命名空间"A"中的函数foo() </span><span style="color: #008080;"> 8</span> <span style="color: #008000;"> // 再尝试调用全局函数 "foo"</span> <span style="color: #008080;"> 9</span> <span style="color: #008080;">10</span> \foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局空间函数 "foo" </span> <span style="color: #008080;">11</span> <span style="color: #008080;">12</span> my\foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用定义在命名空间"A\my"中函数 "foo" </span> <span style="color: #008080;">13</span> <span style="color: #008080;">14</span> F(); <span style="color: #008000;">//</span><span style="color: #008000;"> 首先尝试调用定义在命名空间"A"中的函数 "F" </span><span style="color: #008080;">15</span> <span style="color: #008000;"> // 再尝试调用全局函数 "F" </span><span style="color: #008080;">16</span> <span style="color: #008080;">17</span> <span style="color: #008000;">// 类引用</span> <span style="color: #008080;">18</span> <span style="color: #008080;">19</span> <span style="color: #0000ff;">new</span> B(); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建命名空间 "A" 中定义的类 "B" 的一个对象 </span><span style="color: #008080;">20</span> <span style="color: #008000;"> // 如果未找到,则尝试自动装载类 "A\B"</span> <span style="color: #008080;">21</span> <span style="color: #008080;">22</span> <span style="color: #0000ff;">new</span> D(); <span style="color: #008000;">//</span><span style="color: #008000;"> 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象 </span><span style="color: #008080;">23</span> <span style="color: #008000;"> // 如果未找到,则尝试自动装载类 "B\D"</span> <span style="color: #008080;">24</span> <span style="color: #008080;">25</span> <span style="color: #0000ff;">new</span> F(); <span style="color: #008000;">//</span><span style="color: #008000;"> 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象 </span><span style="color: #008080;">26</span> <span style="color: #008000;"> // 如果未找到,则尝试自动装载类 "C\E"</span> <span style="color: #008080;">27</span> <span style="color: #008080;">28</span> <span style="color: #0000ff;">new</span> \B(); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建定义在全局空间中的类 "B" 的一个对象 </span><span style="color: #008080;">29</span> <span style="color: #008000;"> // 如果未发现,则尝试自动装载类 "B"</span> <span style="color: #008080;">30</span> <span style="color: #008080;">31</span> <span style="color: #0000ff;">new</span> \D(); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建定义在全局空间中的类 "D" 的一个对象 </span><span style="color: #008080;">32</span> <span style="color: #008000;"> // 如果未发现,则尝试自动装载类 "D"</span> <span style="color: #008080;">33</span> <span style="color: #008080;">34</span> <span style="color: #0000ff;">new</span> \F(); <span style="color: #008000;">//</span><span style="color: #008000;"> 创建定义在全局空间中的类 "F" 的一个对象 </span><span style="color: #008080;">35</span> <span style="color: #008000;"> // 如果未发现,则尝试自动装载类 "F" </span><span style="color: #008080;">36</span> <span style="color: #008080;">37</span> <span style="color: #008000;">// 调用另一个命名空间中的静态方法或命名空间函数</span> <span style="color: #008080;">38</span> <span style="color: #008080;">39</span> B\foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用命名空间 "A\B" 中函数 "foo"</span> <span style="color: #008080;">40</span> <span style="color: #008080;">41</span> B::foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法 </span><span style="color: #008080;">42</span> <span style="color: #008000;"> // 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"</span> <span style="color: #008080;">43</span> <span style="color: #008080;">44</span> D::foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法 </span><span style="color: #008080;">45</span> <span style="color: #008000;"> // 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"</span> <span style="color: #008080;">46</span> <span style="color: #008080;">47</span> \B\foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用命名空间 "B" 中的函数 "foo" </span> <span style="color: #008080;">48</span> <span style="color: #008080;">49</span> \B::foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用全局空间中的类 "B" 的 "foo" 方法 </span><span style="color: #008080;">50</span> <span style="color: #008000;"> // 如果类 "B" 未找到,则尝试自动装载类 "B" </span><span style="color: #008080;">51</span> <span style="color: #008080;">52</span> <span style="color: #008000;">// 当前命名空间中的静态方法或函数</span> <span style="color: #008080;">53</span> <span style="color: #008080;">54</span> A\B::foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法 </span><span style="color: #008080;">55</span> <span style="color: #008000;"> // 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"</span> <span style="color: #008080;">56</span> <span style="color: #008080;">57</span> \A\B::foo(); <span style="color: #008000;">//</span><span style="color: #008000;"> 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法 </span><span style="color: #008080;">58</span> <span style="color: #008000;"> // 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"</span> <span style="color: #008080;">59</span> ?>
<span class="pun"> </span>
名称解析遵循下列规则: