在一个PHP文件中使用全局命名空间和多个命名空间会增加代码的复杂性并降低可读性。
让我们尽量避免使用这种方案,即使非常必要(尽管实际上并非如此)。
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
可以在同一文件中声明多个命名空间。有两种允许的语法。
示例 #1 声明多个命名空间,简单的组合语法
<?php
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>
不推荐这种将命名空间组合到单个文件的语法。建议使用另一种带括号的语法。
示例 #2 声明多个命名空间,带括号的语法
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
强烈不建议将多个命名空间组合到同一个文件中。主要用例是将多个PHP脚本组合到同一个文件中。
要将全局非命名空间代码与命名空间代码组合,只支持带括号的语法。全局代码应包含在没有命名空间名称的命名空间语句中,如下所示:
示例 #3 声明多个命名空间和非命名空间代码
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
除了打开的 `declare` 语句外,任何PHP代码都不能存在于命名空间括号之外。
示例 #4 声明多个命名空间和非命名空间代码
<?php
declare(encoding='UTF-8');
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // 全局代码
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
在一个PHP文件中使用全局命名空间和多个命名空间会增加代码的复杂性并降低可读性。
让我们尽量避免使用这种方案,即使非常必要(尽管实际上并非如此)。
<?php
// 你不能将带括号的命名空间声明与不带括号的命名空间声明混合使用 - 会导致致命错误
namespace a;
echo "我属于命名空间a";
namespace b {
echo "我来自命名空间b";
}
<?php
//命名空间也可以这样使用
namespace MyProject {
function connect() { echo "ONE"; }
Sub\Level\connect();
}
namespace MyProject\Sub {
function connect() { echo "TWO"; }
Level\connect();
}
namespace MyProject\Sub\Level {
function connect() { echo "THREE"; }
\MyProject\Sub\Level\connect(); // 或者我们可以像下面这样使用
connect();
}
如果你习惯在测试文件中始终使用闭合的PHP标签“?>”,请记住,使用方括号语法时,方括号外的代码,包括PHP标签外的换行符,都是不允许的。特别是,即使PHP将闭合标签后的换行符视为该行的一部分并将其忽略,某些编辑器(例如Ubuntu中的Gedit、Gvim、Vim和Nano)仍会在该换行符后添加另一个换行符,这将导致错误。
有一些合理的例子表明,将多个命名空间混合到单个文件中的能力不仅是可取的,而且是绝对必要的。一个这样的例子存在于非常流行的phpseclib库中,它符合PSR-4规范,但是为了符合该规范,它必须读取一个文件目录以知道哪些类可用,以便自动加载器可以加载正确的文件。如果他们只是使用PHP核心已经支持的这种机制将默认值捆绑到一个文件中,则无需进行多余的文件系统扫描。
这只是一个合法的用例,其中严格遵守PSR规范妨碍了良好的软件开发。
//使用命名空间调用同名函数
//food.php
<?php
namespace Food;
require ('Apple.php');
require('Orange.php');
use Apples;
use Oranges;
Apples\eat();
Oranges\eat();
?>
//Apple.php
<?php
namespace Apples;
function eat()
{
echo "eat apple";
}
?>
//Orange.php
<?php
namespace Oranges;
function eat()
{
echo "eat Orange";
}
?>