• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    PHP命名空间(namespace)原理与用法详解

    本文实例讲述了PHP命名空间(namespace)原理与用法。分享给大家供大家参考,具体如下:

    PHP 命名空间(namespace)是在PHP 5.3中加入的,它可以解决以下两类问题:

    1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
    2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

    我们在默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样,命名空间通过关键字namespace 来声明,如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。我们来看下语法:

    ?php 
    // 定义代码在 'MyProject' 命名空间中 
    namespace MyProject; 
    // ... 代码 ...
    
    

    我们也可以在同一个文件中定义不同的命名空间代码,如下:

    ?php 
    namespace MyProject;
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */ }
    namespace AnotherProject;
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */ }
    ?>
    
    

    不过我不建议使用这种语法在单个文件中定义多个命名空间,有需要的话,可以使用大括号形式的语法,如下:

    ?php
    namespace MyProject {
      const CONNECT_OK = 1;
      class Connection { /* ... */ }
      function connect() { /* ... */ }
    }
    namespace AnotherProject {
      const CONNECT_OK = 1;
      class Connection { /* ... */ }
      function connect() { /* ... */ }
    }
    ?>
    
    

    我们如果要将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法,并且全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,如下:

    ?php
    namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */ }
    }
    namespace { // 全局代码
    session_start();
    $a = MyProject\connect();
    echo MyProject\Connection::start();
    }
    ?>
    
    

    我们在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句,要记住,除了这个之外的所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前,如下:

    ?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();
    }
    ?>
    
    

    看个错误的写法:

    html>
    ?php
    namespace MyProject; // 命名空间前出现了“html>” 会致命错误 - 命名空间必须是程序脚本的第一条语句
    ?>

    与目录和文件的关系很像,PHP 命名空间也允许指定层次化的命名空间的名称,因此,命名空间的名字可以使用分层次的方式定义,模式如下:

    ?php
    namespace MyProject\Sub\Level; //声明分层次的单个命名空间
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function Connect() { /* ... */ }
    ?>
    
    

    上述代码中,创建了常量 MyProject\Sub\Level\CONNECT_OK,类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。

    咱们再来看下PHP 命名空间中的类名的引用方式:

    1. 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
    2. 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
    3. 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

    咱们用来个文件来演示下,首先来看f1.php的代码:

    ?php
    namespace Foo\Bar\subnamespace; 
    const FOO = 1;
    function foo() {}
    class foo
    {
      static function staticmethod() {}
    }
    ?>
    
    

    之后就是f2.php的代码:

    ?php
    namespace Foo\Bar;
    include 'f1.php';
    const FOO = 2;
    function foo() {}
    class foo
    {
      static function staticmethod() {}
    }
    /* 非限定名称 */
    foo(); // 解析为函数 Foo\Bar\foo
    foo::staticmethod(); // 解析为类 Foo\Bar\foo ,方法为 staticmethod
    echo FOO; // 解析为常量 Foo\Bar\FOO
    /* 限定名称 */
    subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
    subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,
                     // 以及类的方法 staticmethod
    echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO
    /* 完全限定名称 */
    \Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
    \Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
    echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
    ?>
    
    

    我们访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。之后,咱们再来看下在命名空间内部访问全局类、函数和常量的实例:

    ?php
    namespace Foo;
    function strlen() {}
    const INI_ALL = 3;
    class Exception {}
    $a = \strlen('hi'); // 调用全局函数strlen
    $b = \INI_ALL; // 访问全局常量 INI_ALL
    $c = new \Exception('error'); // 实例化全局类 Exception
    ?>
    
    

    PHP 命名空间的实现受到其语言自身的动态特征的影响,我们先来看一段代码:

    ?php
    class classname
    {
      function __construct()
      {
        echo __METHOD__,"\n";
      }
    }
    function funcname()
    {
      echo __FUNCTION__,"\n";
    }
    const constname = "global";
    $a = 'classname';
    $obj = new $a; // prints classname::__construct
    $b = 'funcname';
    $b(); // prints funcname
    echo constant('constname'), "\n"; // prints global
    ?>
    
    

    我们如果要将上述的代码转换到命名空间中,并且动态访问元素,就必须使用完全限定名称(包括命名空间前缀的类名称)。注意因为在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的。如下:

    ?php
    namespace namespacename;
    class classname
    {
      function __construct()
      {
        echo __METHOD__,"\n";
      }
    }
    function funcname()
    {
      echo __FUNCTION__,"\n";
    }
    const constname = "namespaced";
    include 'example1.php';
    $a = 'classname';
    $obj = new $a; // 输出 classname::__construct
    $b = 'funcname';
    $b(); // 输出函数名
    echo constant('constname'), "\n"; // 输出 global
    /* 如果使用双引号,使用方法为 "\\namespacename\\classname"*/
    $a = '\namespacename\classname';
    $obj = new $a; // 输出 namespacename\classname::__construct
    $a = 'namespacename\classname';
    $obj = new $a; // 输出 namespacename\classname::__construct
    $b = 'namespacename\funcname';
    $b(); // 输出 namespacename\funcname
    $b = '\namespacename\funcname';
    $b(); // 输出 namespacename\funcname
    echo constant('\namespacename\constname'), "\n"; // 输出 namespaced
    echo constant('namespacename\constname'), "\n"; // 输出 namespaced
    ?>
    
    

    好啦,本次记录就到这里了,后续的记录会在之后的文章中有体现。

    更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

    希望本文所述对大家PHP程序设计有所帮助。

    您可能感兴趣的文章:
    • 详细分析PHP 命名空间(namespace)
    • PHP类的自动加载与命名空间用法实例分析
    • PHP 命名空间和自动加载原理与用法实例分析
    • PHP 命名空间原理与用法详解
    • php 命名空间(namespace)原理与用法实例小结
    • PHP命名空间用法实例分析
    • PHP命名空间与自动加载机制的基础介绍
    • php的命名空间与自动加载实现方法
    • 详解PHP中的命名空间
    上一篇:在 Laravel 6 中缓存数据库查询结果的方法
    下一篇:记Laravel调用Gin接口调用formData上传文件的实现方法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    PHP命名空间(namespace)原理与用法详解 PHP,命名,空间,namespace,原理,