• 目录启示:使用 use 关键字为命名空间内的元素建立非限定名称


    参考

    环境

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

    三种名称

    在 PHP 命名空间的上下文中,限定名称 (Qualified Name)、非限定名称 (Unqualified Name) 与完全限定名称 (Fully Qualified Name) 是 三种引用命名空间中的元素(类、接口、函数 与 常量)的方式

    非限定名称

    非限定名称是一个 不包含任何命名空间前缀的名称,如 ClassName 就是一个非限定名称。当使用非限定名称时,PHP 会 优先在当前命名空间中查找该元素。若该原始不存在于当前命名空间中,则将在全局命名空间中对其进行查找(仅当被查找元素为函数或常量时)

    限定名称

    限定名称包含 命名空间前缀,但没有开头的反斜线 \(该反斜线表示全局命名空间)。如 NamespaceName\ClassNameNamespaceName\functionName() 就是限定名称。当使用限定名称时,PHP 会 基于当前命名空间来解析该名称

    完全限定名称

    完全限定名称从反斜线 \(该反斜线表示全局命名空间) 开始,后接命名空间或元素的名称。如 \Full\NamespaceName\ClassName\Full\NamespaceName\functionName() 就是完全限定名称。当使用完全限定名称时,PHP 会 完全忽略当前命名空间的上下文,并从全局上下文解析名称

    举个栗子

    
    
    
    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

    use

    use 关键字

    在 PHP 中,use 关键字用于导入命名空间中的 接口函数常量,以便在当前命名空间中直接使用这些元素的 非限定名称,有助于提高开发体验😎。对此,请参考如下示例:

    
    
    
    namespace HOME\RedHeart\BinaryMoon {
        const CONSTANT = __NAMESPACE__;
        class MyClass
        {
            public $name = 'RedHeart';
            public $nation = 'China';
            public $age = 18;
        }
        function sayHello() {
            print("Hello World\n");
        }
    }
    
    namespace {
        # 将 \HOME\RedHeart\BinaryMoon\ 命名空间下的
        # MyClass 类导入至当前命名空间,便可以使用非限定名称访问该类。
        use \HOME\RedHeart\BinaryMoon\MyClass;
        var_dump(new MyClass());
    
        # 将 \HOME\RedHeart\BinaryMoon\ 命名空间下的
        # 函数 sayHello 与常量 CONSTANT 导入当前命名空间
        use function HOME\RedHeart\BinaryMoon\sayHello;
        use const HOME\RedHeart\BinaryMoon\CONSTANT;
    
        sayHello();
        print(CONSTANT . "\n");
    }
    
    • 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

    执行效果

    在 PHP 中,use 关键字的默认操作对象是 。若您需要将 函数常量 导入至当前命名空间,请在 use 关键字后添加 functionconst 以告知 PHP 解释器

    object(HOME\RedHeart\BinaryMoon\MyClass)#1 (3) {
      ["name"]=>
      string(8) "RedHeart"
      ["nation"]=>
      string(5) "China"
      ["age"]=>
      int(18)
    }
    Hello World
    HOME\RedHeart\BinaryMoon
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    use … as …

    在 PHP 中,use ... as ... 语句用于导入命名空间中的 接口函数常量并为它们创建一个 别名,以便可以在当前代码块中使用别名来引用相关的元素。对此,请参考如下示例:

    
    
    
    namespace HOME\RedHeart\BinaryMoon {
        const CONSTANT = __NAMESPACE__;
        class MyClass
        {
            public $name = 'RedHeart';
            public $nation = 'China';
            public $age = 18;
        }
        function sayHello() {
            print("Hello World\n");
        }
    }
    
    namespace {
        use \HOME\RedHeart\BinaryMoon\MyClass as AnClass;
        use function HOME\RedHeart\BinaryMoon\sayHello as speakHello;
        use const HOME\RedHeart\BinaryMoon\CONSTANT as ANCONSTANT;
    
        var_dump(new AnClass());
        speakHello();
        print(ANCONSTANT . "\n");
    }
    
    • 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

    执行效果

    object(HOME\RedHeart\BinaryMoon\MyClass)#1 (3) {
      ["name"]=>
      string(8) "RedHeart"
      ["nation"]=>
      string(5) "China"
      ["age"]=>
      int(18)
    }
    Hello World
    HOME\RedHeart\BinaryMoon
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    命名冲突

    真假美猴王

    
    
    
    namespace BinaryMoon {
        class BinaryMoon {}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在上述示例中,命名空间 BinaryMoon 与其 类元素 BinaryMoon 使用相同名称。按照正常情况,两者将发生 命名冲突,但上述示例却能够正常执行。这是由于,命名空间 BinaryMoon 的完全限定名称是 \BinaryMoon,而 类元素 BinaryMoon 的完全限定名称是 \BinaryMoon\BinaryMoon,两者的名称 并不真的相同

    两个世界

    实际上,命名空间与其他元素之间并不会产生命名冲突,即使两者的完全限定名称一模一样。对此,请参考如下示例:

    
    
    
    namespace BinaryMoon {}
    
    namespace {
        class BinaryMoon {}
    
        var_dump(new \BinaryMoon());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行效果

    在使用 class 关键字创建类 BinaryMoon 后,类与命名空间具有相同的完全限定名称 \BinaryMoon,这并不会导致两者发生 命名冲突,PHP 会 依据具体情景进行分析来确定如何解析该名称。但程序并非完美的,它无法应对所有可能的场景,鉴于此,请 尽可能不要尝试使用相同的名称

    object(BinaryMoon)#1 (0) {
    }
    
    • 1
    • 2

  • 相关阅读:
    【洛谷题解/AcWing题解/NOIP2006提高组】P1064/AcWing481 金明的预算方案
    Pytorch 自动求导的设计与实现
    Vert.x 源码解析(4.x)(一)——Future源码解析
    Go短网址项目实战---上
    springcloud之config配置中心
    易趋云亮相第七届SaaS应用大会
    如何让 Llama2、通义千问开源大语言模型快速跑在函数计算上?
    【测试】1. 概念 + 基础篇
    寻找AI-Native创业者
    Spring 拦截器实现请求拦截与参数处理【拦截器(Interceptor)和过滤器(Filter)的区别】
  • 原文地址:https://blog.csdn.net/qq_44879989/article/details/133818237