• 目录启示:PHP 中 命名空间及其成员的访问


    参考

    环境

    项目描述
    PHP5.5.05.6.87.0.07.2.57.4.98.0.08.2.9
    PHP 编辑器PhpStorm 2023.1.1(专业版)

    命名空间的使用

    全局命名空间成员

    全局命名空间成员是指位于 PHP 全局命名空间下的 接口函数常量。全局命名空间是 PHP 脚本的默认命名空间,也被称为 根命名空间

    
    
    
    # 定义全局命名空间成员 MyClass、CONSTANT 以及 func。
    class MyClass {}
    const CONSTANT = "";
    function func() {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在上述示例中,我们定义了全局命名空间成员 \MyClass\CONSTANT 以及 \func。其中,\ 指代全局命名空间。在全局命名空间中访问全局命名空间成员可以不添加 \ 前缀,但在其他命名空间中对全局命名空间成员进行访问则 推荐使用前缀,否则很可能将 使用当前命名空间下的同名成 员。对此,请参考如下示例:

    
    
    
    # 全局命名空间
    namespace {
        const HOME = 'BinaryMoon';
    }
    
    # 命名空间 \RedHeart
    namespace RedHeart {
        const HOME = 'China';
    
        # 尝试访问常量 HOME
        var_dump(HOME);
        var_dump(\HOME);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    执行效果

    string(5) "China"
    string(10) "BinaryMoon"
    
    • 1
    • 2

    HOME 在命名空间 RedHeart 中的 完全限定名称(可以将其理解为绝对路径)\RedHeart\HOME,在使用 接口函数常量 这些受命名空间影响的组份时,若没有对名称进行 限定(可以理解为相对路径中的一种,相对当前目录进行文件的访问),则将视该名称为当前命名空间成员所属。
    由于 HOME 属于未限定名称,故其被解析为 \RedHeart\HOME,而 \HOME 属于完全限定名称,故将使用全局命名空间下的 HOME 常量。

    子命名空间成员

    声明命名空间时,命名空间所使用的名称均是相对于全局命名空间进行命名的。而在 访问命名空间成员时,则存在三种名称,这三种名称分别可与 类 Unix(如 Linux) 系统中的绝对路径、相对路径相对应。具体如下:

    1. 完全限定名称
      完全限定名称表明了从全局命名空间到目标命名空间所经历的一系列命名空间,如 \HOME\RedHeart\BinaryMoon 就是一个完全限定名称。完全限定名称可与 类 Unix 系统中的绝对路径进行类比。
    2. 限定名称
      限定名称表明了从当前命名空间到目标命名空间所经历的一系列命名空间,如在 \HOME 命名空间中使用的 RedHeart\BinaryMoon 就是一个限定名称,其完全限定名称为 \HOME\RedHeart\BinaryMoon。限定名称可与 类 Unix 系统中的相对路径进行类比。
    3. 非限定名称
      非限定名称仅仅使用单个命名空间名称表示需要访问的命名空间,如在 \HOME 命名空间中使用的 RedHeart 就是一个非限定名称,其完全限定名称为 \HOME\RedHeart。非限定名称同样可与 类 Unix 系统中的相对路径进行类比。
    
    
    
    namespace HOME\RedHeart {
        function saySelf() {
            # 通过魔术常量 __NAMESPACE 回当前所属的命名空间名称
            return __NAMESPACE__;
        }
    
        function saySon() {
            # 尝试访问当前命名空间中的子命名空间 BinaryMoon 中的 saySelf() 函数
            return BinaryMoon\saySelf();
        }
    }
    
    namespace HOME\RedHeart\BinaryMoon {
        function saySelf() {
            return __NAMESPACE__;
        }
    }
    
    # 全局命名空间
    namespace {
        # 尝试访问 HOME\RedHeart\BinaryMoon 命名空间下的 saySelf() 函数
        var_dump(\HOME\RedHeart\BinaryMoon\saySelf());
        # 尝试访问 HOME\RedHeart 命名空间下的 saySelf() 函数
        var_dump(HOME\RedHeart\saySelf());
        # 尝试访问 HOME\RedHeart 命名空间下的 saySon() 函数
        var_dump(\HOME\RedHeart\saySon());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    执行效果

    string(24) "HOME\RedHeart\BinaryMoon"
    string(13) "HOME\RedHeart"
    string(24) "HOME\RedHeart\BinaryMoon"
    
    • 1
    • 2
    • 3

    namespace 关键字

    namespace 的两大功能

    在 PHP 中,namespace 关键字常用于 命名空间的声明当前命名空间下元素的访问

    使用 namespace\ 访问当前命名空间下的元素

    在使用 namespace 访问当前命名空间元素时,namespace 后需要紧跟反斜线 \,后跟子命名空间或 其他元素(类、接口、函数 和 常量)。对此请参考如下示例:

    
    
    
    namespace HOME\RedHeart {
        const CONSTANT = __NAMESPACE__;
        function func() {}
        class MyClass {}
    }
    
    namespace HOME\RedHeart\BinaryMoon {
        const CONSTANT = __NAMESPACE__;
        function func() {}
        class MyClass {}
    }
    
    namespace HOME\RedHeart {
        # 访问当前命名空间下除子命名空间外的其他元素
        var_dump(namespace\CONSTANT);
        new namespace\MyClass();
        namespace\func();
        # 访问当前命名空间的子命名空间 BinaryMoon 内的元素
        var_dump(namespace\BinaryMoon\CONSTANT);
        new namespace\BinaryMoon\MyClass();
        namespace\BinaryMoon\func();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    执行结果

    string(13) "HOME\RedHeart"
    string(24) "HOME\RedHeart\BinaryMoon"
    
    • 1
    • 2

    未雨绸缪

    第一深情

    在使用非限定名称对元素进行访问时,类名称 总是基于当前命名空间进行解析。因此 在其他命名空间中尝试访问全局命名空间中的类时,必须使用完全限定名称。对此,请参考如下示例:

    
    
    
    namespace {
        # 在全局命名空间中定义类 MyClass
        class MyClass {}
    }
    
    namespace HOME {
        # 在 \HOME 全局命名空间中尝试
        # 使用非限定名称对 \MyClass 类进行访问
        $myClass = new MyClass();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    执行效果

    即使在 当前命名空间中(非全局命名空间) 未找到名为 MyClass 的类,PHP 也 不会尝试将其解析为全局命名空间中的元素

    PHP Fatal error:  Uncaught Error: Class 'HOME\MyClass' not found in C:\test.php:12
    Stack trace:
    #0 {main}
      thrown in C:\test.php on line 12
    
    • 1
    • 2
    • 3
    • 4

    向上突围

    函数与常量的名称与类名称的解析存在差异。在使用非限定名称对元素进行访问时,如果当前命名空间中不存在该函数或常量,PHP 会 退而使用全局空间中的函数或常量。对此,请参考如下示例:

    
    
    
    namespace {
        # 在全局命名空间中定义函数 sayHello 与 常量 CONSTANT
        function sayHello() {
            print('Hello World' . "\n");
        }
    
        const CONSTANT = __NAMESPACE__;
    }
    
    namespace HOME {
        # 在 \HOME 命名空间中,
        # 尝试使用非限定名称对元素进行访问。
        sayHello();
        var_dump(CONSTANT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    执行效果

    Hello World
    string(0) ""
    
    • 1
    • 2

    (完全)限定名称下的未定义常量

    PHP8 以下

    在 PHP8 以下版本中,尝试访问未定义常量将导致 Warning 异常,该常量的名称的字符串形式将作为访问结果。对此,请参考如下示例:

    
    
    
    # 尝试访问未定义常量
    var_dump(CONSTANT);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    执行效果

    PHP7.2.5 中执行上述代码,得到如下结果:

    PHP Warning:  Use of undefined constant CONSTANT - assumed 'CONSTANT' (this will throw an Error in a future version of PHP) in C:\test.php on line 5
    string(8) "CONSTANT"
    
    • 1
    • 2

    PHP8 及以上

    在 PHP8 及以上版本中,尝试访问未定义常量将导致 Fatal 异常,PHP 将因此立即终止程序。对此,请参考如下示例:

    
    
    # 尝试访问未定义常量
    var_dump(CONSTANT);
    
    • 1
    • 2
    • 3
    • 4

    执行效果

    PHP8.0.0 中执行上述代码,得到如下结果:

    PHP Fatal error:  Uncaught Error: Undefined constant "CONSTANT" in C:\test.php:5
    Stack trace:
    #0 {main}
      thrown in C:\test.php on line 5
    
    • 1
    • 2
    • 3
    • 4

    任何情况下的(完全)限定名称下的未定义常量

    在任何 PHP 版本中,使用完全限定名称或限定名称对未定义常量进行访问都将导致 Fatal 异常,PHP 程序都将为此立即终止。对此,请参考如下示例:

    
    
    
    # 尝试访问未定义常量
    namespace HOME\RedHeart {
    }
    
    namespace HOME {
        # 尝试通过完全限定名称对未定义常量进行访问
        var_dump(\HOME\RedHeart\CONSTANT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    
    
    
    # 尝试访问未定义常量
    namespace HOME\RedHeart {
    }
    
    namespace HOME {
        # 尝试通过限定名称对未定义常量进行访问
        var_dump(RedHeart\CONSTANT);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    执行效果

    PHP7.2.5 中,执行上述两组示例都将得到如下类似结果:

    PHP Fatal error:  Uncaught Error: Undefined constant 'HOME\RedHeart\CONSTANT' in C:\test.php:10
    Stack trace:
    #0 {main}
      thrown in C:\test.php on line 10
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    HarmonyOS 性能优化
    第十九章 cookie和session
    PostgreSQL-基本结构
    盘点52个Python各行各业管理系统源码Python爱好者不容错过
    智能计量插座多角色定位:用电监测&资产管理的智能化强大运用
    <Python>PyQt5自己编写一个音乐播放器(优化版)
    Redis 缓存过期淘汰策略
    二叉树高度
    TikTok本周动态,TikTok Shop新加坡首场大促将于本月举行
    从软件测试培训班出来后找工作这段时间的经历,教会了我这五件事...
  • 原文地址:https://blog.csdn.net/qq_44879989/article/details/133818196