PHP基础参考12-命名空间
目录
命名空间
命名空间可以类比unix系统文件路径。在操作系统中文件有文件路径,用于区分相同文件名的不同文件。命名空间接地气点解释就是类库、类、函数等的一个路径,解决命名冲突,提高代码可读性。
虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。
namespace MyProject\Sub\Level;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
//namespace除了支持类、接口外还支持普通函数与脚本中常量定义
require_once 'functions.php';//functions.php定义namespace为extend,且定义cli_log函数
\extend\cli_log(__FILE__."\t".__LINE__);//来自functions.php的函数
cli_log("我是谁,我来自哪里,我要做什么");//来自当前文件的cli_log函数,命名空间就很好的解决了同名函数的问题
//当前文件下的cli_log
function cli_log($msg){
echo $msg." -- from local file function.\n";
}
-
同一个命名空间可以定义在多个文件中,即允许将同一个命名空间的内容分割存放在不同的文件中。
-
一个文件中定义多个命名空间
namespace MyProject\Sub\Level { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } }
上面的例子创建了常量MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection和函数 MyProject\Sub\Level\connect。
还有另外一个命名空间:AnoterhProject。
不建议在一个文件中定义多个命名空间。
命名空间使用
命名空间的使用也可以类比unix系统文件路径使用。
相对路径、绝对路径
namespace A\B\C;
/* 这个函数是 A\B\C\fopen */
function fopen() {
/* ... */
$f = \fopen(...); // 调用全局的fopen函数
return $f;
}
namespace A\B\C;
class Exception extends \Exception {}
$a = new Exception('hi'); // $a 是类 A\B\C\Exception 的一个对象
$b = new \Exception('hi'); // $b 是类 Exception 的一个对象
$c = new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
namespace A;
use B\D, C\E as F;
// 函数调用
foo(); // 首先尝试调用定义在命名空间"A"中的函数foo()
// 再尝试调用全局函数 "foo"
\foo(); // 调用全局空间函数 "foo"
my\foo(); // 调用定义在命名空间"A\my"中函数 "foo"
F(); // 首先尝试调用定义在命名空间"A"中的函数 "F"
// 再尝试调用全局函数 "F"
// 类引用
new B(); // 创建命名空间 "A" 中定义的类 "B" 的一个对象
// 如果未找到,则尝试自动装载类 "A\B"
new D(); // 使用导入规则,创建命名空间 "B" 中定义的类 "D" 的一个对象
// 如果未找到,则尝试自动装载类 "B\D"
new F(); // 使用导入规则,创建命名空间 "C" 中定义的类 "E" 的一个对象
// 如果未找到,则尝试自动装载类 "C\E"
new \B(); // 创建定义在全局空间中的类 "B" 的一个对象
// 如果未发现,则尝试自动装载类 "B"
new \D(); // 创建定义在全局空间中的类 "D" 的一个对象
// 如果未发现,则尝试自动装载类 "D"
new \F(); // 创建定义在全局空间中的类 "F" 的一个对象
// 如果未发现,则尝试自动装载类 "F"
// 调用另一个命名空间中的静态方法或命名空间函数
B\foo(); // 调用命名空间 "A\B" 中函数 "foo"
B::foo(); // 调用命名空间 "A" 中定义的类 "B" 的 "foo" 方法
// 如果未找到类 "A\B" ,则尝试自动装载类 "A\B"
D::foo(); // 使用导入规则,调用命名空间 "B" 中定义的类 "D" 的 "foo" 方法
// 如果类 "B\D" 未找到,则尝试自动装载类 "B\D"
\B\foo(); // 调用命名空间 "B" 中的函数 "foo"
\B::foo(); // 调用全局空间中的类 "B" 的 "foo" 方法
// 如果类 "B" 未找到,则尝试自动装载类 "B"
// 当前命名空间中的静态方法或函数
A\B::foo(); // 调用命名空间 "A\A" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\A\B" 未找到,则尝试自动装载类 "A\A\B"
\A\B::foo(); // 调用命名空间 "A\B" 中定义的类 "B" 的 "foo" 方法
// 如果类 "A\B" 未找到,则尝试自动装载类 "A\B"
如果不清楚的,可以参考官方文档:
命名空间导入与别名
use My\Full\Classname as MFC;