在同一个 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 将结束标签后的换行符视为该行的一部分并将其吃掉,但一些编辑器,如 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";
}
?>