美文网首页PHP很简单
命名空间探索——PHP

命名空间探索——PHP

作者: 四月不见 | 来源:发表于2017-08-18 16:37 被阅读8次

    命名空间的介绍

    什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,目录就扮演了命名空间的角色。

    而在PHP当中,命名空间就扮演了目录的角色,而PHP代码中的类(包括抽象类和traits)、接口、函数和常量则就扮演了文件的角色。

    PHP 中的命名空间(namespace)是在PHP 5.3中加入的,主要是为了解决用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。

    命名空间的定义

    默认情况下,所有常量、类和函数名都放在全局空间下,就和PHP支持命名空间之前一样。

    命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间,除了一个以外:declare关键字。语法格式如下;

    < ?php

    // 定义代码在 'MyProject' 命名空间中

    namespace MyProject;

    另外,与PHP其它的语言特征不同,同一个命名空间可以定义在多个文件中,即允许将同一个命名空间的内容分割存放在不同的文件中。

    你也可以在同一个文件中定义不同的命名空间代码,但非常不提倡这一种做法。

    命名空间的使用

    1、Unqualified name(非限定名称)

    名称中不包含命名空间分隔符的标识符,例如Foo

    例如  $a=new foo();foo::staticmethod();。如果当前命名空间是currentnamespace,foo 将被解析为currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。警告:对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量。


    2、Qualified name(限制名称)

    名称中含有命名空间分隔符的标识符,例如Foo\Bar

    例如  $a = new subnamespace\foo();subnamespace\foo::staticmethod();。如果当前的命名空间是currentnamespace,则 foo 会被解析为currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo


    3、Fully qualified name(完全限制名称)

    名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,例如\Foo\Barnamespace\Foo也是一个完全限定名称。

    例如,$a = new \currentnamespace\foo();\currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo


    官方例子:    

    file1.php 文件代码:

    namespace  Foo\Bar\subnamespace;

    const  FOO = 1;

    function  foo() {  }

    class  foo {

        static function staticmethod() {  }

    }

    file2.php文件代码:

    namespace  Foo\Bar;

    include 'one\cantroller\SaySome.php';

    const FOO = 2;

    function foo() {}

    class foo {

        static function staticmethod() {}

    }

    /* 非限定名称 */

    foo(); // 解析为 Foo\Bar\foo

    foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod

    echo FOO; // resolves to constant 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版本支持三种别名或导入方式:为类名称使用别名、为接口使用别名或为命名空间名称使用别名。PHP 5.6开始允许导入函数或常量或者为它们设置别名。

    1、使用use操作符导入/使用别名

    namespace  foo;

    use  My\Full\Classname  as  Another;

    // 下面的例子与 use My\Full\NSname as NSname 相同

    use  My\Full\NSname;

    // 导入一个全局类

    use  \ArrayObject;

    $obj = new namespace\Another; // 实例化 foo\Another 对象

    $obj = newAnother; // 实例化 My\Full\Classname 对象

    NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func

    $a=new ArrayObject(array(1)); // 实例化 ArrayObject 对象

    // 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象

    2、 一行中包含多个use语句

    use My\Full\Classname as Another , My\Full\NSname;

    $obj=new Another; // 实例化 My\Full\Classname 对象

    NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func

    注意事项

    如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间

    虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。

    PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__魔术常量和namespace关键字。

    关键字namespace可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的self操作符。

    参考

    PHP官方手册:命名空间

    相关文章

      网友评论

        本文标题:命名空间探索——PHP

        本文链接:https://www.haomeiwen.com/subject/sooorxtx.html