ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 命名空间概述 在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码(如类或函数时),碰到的两类问题: * 用户编写的代码与PHP内部的类/函数/常量或者第三方类/函数/常量之间的名字冲突 * 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提升源代码的可读性 >[danger] 名为PHP或php的命名空间,以及以这些名字开头的命名空间(例如PHP\Classes)被保留用作语言内核使用,而不应该在用户空间的代码中使用。 # 定义命名空间 (PHP 5 >= 5.3.0, PHP 7) 虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。 命名空间通过关键字namespace 来声明(所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前)。 ## 声明单个命名空间 ~~~ <?php namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?> ~~~ ## 定义子命名空间 与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义 ## 声明分层次的单个命名空间 ~~~ <?php namespace MyProject\Sub\Level; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?> ~~~ ## 在同一个文件中定义多个命名空间 也可以在同一个文件中定义多个命名空间。在同一个文件中定义多个命名空间有两种语法形式。 ### 定义多个命名空间,大括号语法 ~~~ <?php namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } ?> ~~~ ### 定义多个命名空间,简单组合语法(不推荐) ~~~ <?php namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } ?> ~~~ >[info] 在实际的编程实践中,非常不提倡在同一个文件中定义多个命名空间。这种方式的主要用于将多个 PHP 脚本合并在同一个文件中。 [TOC] ## 使用命名空间 **在文件系统中访问一个文件有三种方式** * 相对文件名形式如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 将被解析为 `currentnamespace\foo`。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:[后备全局函数名称/常量名称](http://php.net/manual/zh/language.namespaces.fallback.php)。 * 限定名称,或包含前缀的名称,例如 `$a = new subnamespace\foo();` 或 `subnamespace\foo::staticmethod();`。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 `currentnamespace\subnamespace\foo`。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为`subnamespace\foo`。 * 完全限定名称,或包含了全局前缀操作符的名称,例如, `$a = new \currentnamespace\foo();` 或 `\currentnamespace\foo::staticmethod();`。在这种情况下,foo 总是被解析为代码中的文字名`(literal name)currentnamespace\foo`。