目录

命名空间

命名空间可以类比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"

如果不清楚的,可以参考官方文档:

PHP: 使用命名空间:基础 - Manual

PHP: 名称解析规则 - Manual

命名空间导入与别名

use My\Full\Classname as MFC;

PHP: 使用命名空间:别名/导入 - Manual