• 命名空间


    思考:在php中,函数类和常量都是不允许同名的,一旦同名就会出现冲突。但是在大型项目开发中,团队开发很难避免出现同名结构,此时就会出现同名冲突

    解决的方案只能是刻意去控制不同名吗?

    引入:从开发角度出发,最好的办法就是保证不同名。这样的效率和效果都是最好的,但是在大型项目中,不同团队负责的模块可能不同,那么此时就很难保证出现不同名了,

    因此这个时候就需要引入一种命名空间机制来保证,即使出现了同名结构也不影响整个项目。

    命名空间基础【掌握】

    定义:命名空间namespace,是指认为将内存进行分割,让不同内存区域的同名结构共存,从而解决在大型项目中可能出现的重名结构问题。

    1.基本语法 nameapace 空间名字

    <?php
    
    
    namespace my_space;           //定义一个叫做my_space的空间

    2.命名空间的命名规则

      由字母、下划线和数字构成

      可以以字母和下划线开头

      较少出现多单词空间名,一个使用下划线法

    3.命名空间的作用:能够创建同名结构,包含函数,常量和类

    <?php
    
    
    namespace my_space;           //定义一个叫做my_space的空间
    function show(){
        echo __METHOD__;
    }
    
    namespace my_space2;
    $name='30';
    class posen{
    
        function show(){
            echo '同名的函数,也不报错';
        }
    }

    注意,在一个空间中不可以重名。

    4.命名空间里面的内容

      命名空间里面可以定义同名函数、常量和类(结构),因此类结构不允许同名,这些是命名空间规范的目标(称为空间元素)

      命名空间里面可以有其他代码

    <?php
    
    
    namespace my_space;           //定义一个叫做my_space的空间
    function show(){
        echo __METHOD__;
    }
    
    namespace my_space2;
    $name='30';        //变量
    echo $name;         //变量输出
    class posen{         //
    
        public $name='杜';     //类属性
        function show(){       //类成员
            echo '同名的函数,也不报错';
        }
    
    }

    5.命名空间注意事项:命名空间的声明(第一次)必须在所有代码之前

    <?php
    
    namespace my_space;        //命名空间之前不能有任何代码
    <?php
    
    $age=666;
    namespace my_space;       //错误,第一次命名空间之前不能有任何代码

    注意:命名空间在一个脚本中只会定义一个(最开始),但是在讲课的时候可能会定义多个

      总结

      1.命名空间是使用namespace+空间的名称

      2.不同命名空间可以定义同名函数、常量和类(同名结构)

      3.命名空间里可以书写任意代码

      4.命名空间的定义必须在脚本的最前面

      5.一个脚本中通常只会定义一个空间

      6.命名空间其实就好比是磁盘上划分不同文件夹,用来保存同名文件

    思考:命名空间既然是用来划分空间的,那么能否像文件夹层级那样?实现多层级的命名空间呢?

    引入:命名空间本身就是建立一种虚拟的“围栏”,用来区分不同位置的同名结构,既然可以在内存中设置一层“围栏”,那么自然也可以设置多层,

    这个就叫做子空间

    命名空间子空间【掌握】

    定义:子空间,既在已有的空间上,再在内部进行空间划分,让每个小空间独立起来

    1.命名空间子空间是直接通过namespace+路径符号 实现

    <?php
    
    
    namespace my_space;     //创建一个一级空间
    function display(){};
    
    //创建一个子空间
    namespace my_spacechild;   //在my_space空间下创建一个子空间child
    function displat(){};

    2.子空间的创建不一定非要在前面创建了上级空间,即可以直接在某个脚本中创建子空间

    namespace spaceparent;
    function display(){};

    总结:

      1.子空间也是通过namespace实现,用namespace+路径区分上下级空间名

      2.基于一个脚本中通常只有一个空间名,所以子空间的创建可以直接创建(不用一定先创建一级空间)、

      3.子空间理论上可以创建无限层级,但是实际层级根据项目需求确定(一般不超过四层)

    思考:有了命名空间后,可以在同一个文件里定义不同空间,然后出现同名结构,那如何进行访问呢?

    引入:其实空间就像文件夹一样,同一个文件里不能有同名文件,但是不同文件夹下肯定可以出现同名文件的,而

    如果进行访问的话,就需要进入到不同的空间进行访问。

    空间元素访问【掌握】

    定义:命名空间访问,是指访问不同空间里的结构元素,如果空间里有除了函数、常量和类的其他代码,会自动执行

    只有空间元素本身(函数、常量和类)是需要通过空间进行访问的,在php命名空间中,提供了三种空间元素的访问方式:

    非限定名称,限定名称和完全限定名称。

    1.非限定名称访问:即直接访问空间元素的名字,此类访问的是当前代码所属空间内的元素

    <?php
    
    
    namespace my_space;
    function show(){
        echo __FUNCTION__;
    }
    
    namespace my_space3;
    function show(){
        echo __FUNCTION__;
    }
    
    
    //访问空间元素:非限定名称(直接使用结构名字)
    show();           //显示的是my_space3 show    调用show函数是在my_space3空间下

    注意:非限定名称访问就好比是访问当前自己文件夹下的所有文件

    2.限定名称访问,即在访问元素的前面使用相应的空间名字,非限定名称的访问时基于子空间来实现的

    <?php
    
    //定义子空间
    namespace my_spacefiles;
    function show(){
        echo __FUNCTION__;
    }
    
    
    //定义子空间
    namespace my_spacefiles1;
    function show(){
        echo "我是files1子空间";
    }
    
    
    //定义父空间
    namespace my_space;
    function show(){
        echo "我是父空间";
    }
    show();                 //父空间访问
    filesshow();           //子空间files 实际为当前空间my_space+filesshow()

    注意:限定名称访问好比访问当前文件夹下的子文件夹内容

    3.完全限定名称访问,即从根鲁姆(全局)开始访问,使用作为全局空间开始符号

    <?php
    
    //定义子空间
    namespace files;
    function show(){
        echo __FUNCTION__;
    }
    
    
    //定义子空间
    namespace files1;
    function show(){
        echo "我是files1子空间";
    }
    
    
    //定义父空间
    namespace my_space;
    function show(){
        echo "我是父空间";
    }
    
    //在房钱my_space空间下 使用全局限定来访问files中的show结构
    
    filesshow();          //使用 开始符号 全局限定   返回files show

    注意:完全限定名称访问好比从磁盘根目录访问对应路径下的内容(绝对路径)

    总结:

      1.命名空间的访问分为三种模式

      非限定名称访问:直接访问元素本身,代表当前所属空间(当前目录)

      限定名称访问:使用空间名+元素,代表访问当前空间子空间(当前目录子目录)

      完全限定名称访问:使用全局空间开始,代表从全局开始进行访问(根目录)

     思考:是不是有了命名空间,所有的文件都必须指定空间,如果不指定会怎么样?

    引入:并非所有情况下都需要使用命名空间,命名空间时针对有些可能出现重名的内容时,才会使用的

    另外,如果不使用命名空间,本质系统也认为使用了空间,这就是全局空间

    全局空间【掌握】

    定义:全局空间,即空间元素在没有定义空间的情况下所属的空间,也是所有定义的空间的顶级空间,(即所有空间都是从全局空间分离出来的)

    1.没有指定空间的元素所属空间属于全局空间

    <?php
    
    function show(){
        echo __NAMESPACE__;
    }
    
    show();         //输出无   全局空间没有名字

    2.所有空间本质都是在全局空间下划分的

    <?php
    
    namespace space;
    function show(){
        echo __NAMESPACE__;
    }
    
    show();        //space空间属于从全局空间划分一部分用于space空间管理

    3.全局空间元素访问,使用完全限定名称访问

    <?php
    
    function show(){
        echo __NAMESPACE__;
    }
    
    show();        //非限定名称访问:本身当前就是全局空间内,所以可以访问
    show();     //完全新丁名称访问,全局符号+全局空间元素

    4.一旦命名空间出现,那么空间元素(类,常量和函数)的访问就被限定在空间内,如果使用非限定名称访问,那么系统会以下解析(限定名称或者完全限定名称是直接按路径准确找)

      首先,一定是在自己的空间内查找

      如果找不到元素,不同空间元素的处理不同

        系统常量,系统函数如果找不到,会自动去全局空间找(也就是能找到)

        系统类是不会自动去全局空间找的(报错,提示当前所属空间元素找不到)

    <?php
    
    namespace space;
    //访问空间元素  常量
    echo PHP_VERSION;    //输出7.0.10  为什么能输出,我当前没有定义这个常量,它会去全局空间找
    
    //空间元素——函数访问
    
    echo count(array(1,2,3,4));      //返回4,现在当前空间下找,找不到去找全局空间
    
    //访问空间类
    $conn=new mysqli('localhost','root','root','senven',3306);   //报错 非限定类访问不允许
    //如果想访问需要使用全局限定名称
    $conn=new mysqli('localhost','root','root','senven',3306);

    5.同样的,如果一个文件有空间,包含了一个没有空间的文件,那么要访问文件中的内容,需要使用全局空间

    <?php
    //space01.php文件
    //属于全局空间
    function show(){
        echo __FILE__;
    }
    <?php
    
    namespace sppace;
    //包含无空间文件
    include 'space01.php';
    show();     //可以访问 访问是sppace空间下的show函数
    <?php
    
    namespace sppace;
    
    include 'space01.php';
    show();     //可以访问  访问space下的空间show函数
    show();   //正确,访问全局空间下的show函数
    //注意:如果space空间没有show的话,直接访问show函数也是正确的,因为系统会自动寻找全局空间

    总结:

      1.全局空间就是没有使用namespace定义的空间(所有空间本质都是在全局空间下划分)

      2.全局空间的元素访问使用完全限定名称访问

      3.系统内置的函数,常量和类都属于全局空间

      系统 函数,常量在空间内访问的时候系统会自动在自己空间找,如果找不到会去全局空间找

      系统类必须使用全局空间访问:类名

    思考:既然前面说过一个脚本中通常只会定义一个空间,那么怎么会出现这么多种访问方式呢?

    引入:上述案例只是为了知识本身的规则,在实际应用中一个脚本只会有一个空间,因为一个脚本中通常只有一个类或者一些函数(功能函数)

    但是因为开发的结构性,不同文档所属的功能是不同的,因此也是存放在不同的文件夹的,因此在实现业务的时候会进行文件包含,也就会产生空间包含的问题

    所有就会需要多种访问方式来进行访问。

    命名空间应用【掌握】

    定义:命名空间应用是模拟真实的开发环境,来运用命名空间的规则

    1.创建文件夹:模拟项目不同文件php文件放到不同文件夹下

    --|root                   -------根目录

    --|--|controller                ------业务模块

    --|--|model                  ----数据模块

    --|--|core                  ------核心工具

    2.业务说明

    root根目录:存放用户可以直接访问的文件,文件都是请求controller里的文件

    controller目录:存放业务逻辑文件,所有业务都是类文件,业务要操作数据库,请求model里的文件,属于controller空间

    model目录:存放数据库操作的类文件,一张表一个类文件,属于model空间

    core目录:核心工具的存放,属于core空间

    注意:层层相关,层级结构概念,首先写一个用户操作相关的,需要调用core中的数据库查询(只是个工具),在model数据模型中来想数据库操作(select* from user ),

    在业务逻辑中对model中查询出来的数据进行操作。。。。。。。

    3.创建3个文件:分别代表root目录里下(不需要空间),controller目录下,controller空间,model目录下的model空间

    //core

    core/DB_class.php
    
    <?php
    
    //属于核心空间
    namespace core;
    
    class DB{
        public function __construct(){
            echo '实现了数据的初始化操作<br>';
        }
    
        public function query($sql){
            echo '能够实现数据的查询<br>'.$sql;
        }
    }

    //model

    model/User_class.php
    <?php
    
    
    //属于数据模块空间
    
    namespace model;
    
    //使用core下的操作数据库的类
    include_once 'D:wampwww
    ootcoreDB_class.php';
    
    class User{
        public function getAllUser(){
            $sql='select * from user';    //查询所有的访问
            // $user =new DB();            //非限定名称,在model下面找,找不到 错误
            // $user=new coreDB();        //限定名称在model下找core找db  找不大  错误
            $user=new coreDB();
            return $user->query($sql);
        }
    }

    //controller

    control/User_class.php
    <?php
    
    
    //定义空间
    namespace controller;
    //调用模型目录下的user类实现数据库操作:使用完全限定名称来访问
    
    include_once 'D:wampwww
    ootmodelUser_class.php';
    //业务逻辑模块
    
    //显示用户数据
    class User{
    
        public function index(){
            //获取用户表的数据
            $user=new modelUser();
            $s=$user->getAllUser();
            echo '实现了用户的业务操作<hr>'.$s;
        }
    }

    //入口文件

    root/index.php
    
    <?php
    
    //入口文件
    
    //找到controller中对应的User_class.php
    include_once 'controller/User_class.php';
    
    $u=new controllerUser();
    $u->index();           //返回了数据
    
    //实现了数据的初始化
    //能够实现数据的查询
    //select * from user 实现了用户的业务操作

    代码说明:

      index.php在root目录下没有定义空间,内部元素属于全局空间,index.php包含了子目录controller下的User_class.php,而User类属于controller空间,所以在index.php中访问User类的时候,

    可以使用限定名称(全局的i空间controller空间元素),或者完全限定名称(controller空间元素)

      controller/User_class.php在rootcontroller文件夹下,定义了空间controller,所以文件里面所有访问,默认都在controller下找,controller/User类中用到了modelUser类,所以需要使用完全限定名称访问

    (同级别不同空间)modelUser

      model/User_class.php在rootmodel文件夹下,定义了model空间,所以文件里面所有访问,默认都在model下面找,model/User类中用到了coreDB类,所以需要使用全局限定名称访问coreDB

      coreDB_calss.php在root/core文件夹下,定义了空间core

      总结:

      空间的实际应用是以文件为单位定义空间的

      空间的划分是按业务对应的脚本进行划分的,如业务controller,数据model等

      文件的包含和空间的包含没有联系,二者都是独立的,文件是在加载文件时,而空间在进入内存后

      空间应用,通常是采用非限定名称(自己空间里)和完全限定名称访问(其他空间)

    思考:在实际应该开发中,几乎所有文件都有空间,在进行访问的时候每次都需要使用完全限定名称太麻烦了,有没有什么好的方式呢?

    引入:实际开发中,一般都会进行优化,不会直接使用完全限定名称访问的,并且考虑到继承之类,会出现各种文件包含和空间交互,因此

    为了能够简单的时候,可以采用空间元素引入

    命名空间引入【掌握】

    定义:命名空间引入其实就是将另外一个空间的元素(类,函数和常量)引入到当前空间来,当作当前空空间元素访问,从而可以减少复杂的完全限定名称访问,取而代之的是非限定名称

    访问的方式

    1.空间引入的方式:use关键字

    <?php
    
    namespace space1;
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    }
    
    
    namespace space2;
    //使用完全限定名称方式访问太过麻烦
    // $obj=new space1man();
    // $obj->show();
    
    //使用use关键字引入空间元素
    use space1man;
    
    $obj=new man();
    $obj->show();

    注意:use进行空间包含的时候,默认是从全局空间开始构建空间路径的(不是自己空间的相对路径)所以上述的代码等价于下面的代码

    namespace space2;
    //使用完全限定名称方式访问太过麻烦
    // $obj=new space1man();
    // $obj->show();
    
    //使用use关键字引入空间元素
    use space1man;
    
    $obj=new man();
    $obj->show();

    2.空间引入的元素默认是类,如果要引入其他元素,就必须使用相应的关键字:function和const

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    }
    
    
    namespace space2;
    
    //引入空间元素类
    use space1man;
    //引入空间元素方法
    use function space1add;
    //引入空间元素常量
    use const space1SEX;
    
    //访问space2空间中的函数
    
    add();
    
    //常量
    
    echo SEX;

    3.如果被引用的元素在当前空间已经存在,则会出现重名,解决方案是使用别名 as alias

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    }
    
    
    namespace space2;
    
    //此空间add
    function add(){
        echo __METHOD__;
    }
    
    //由于空间space1中和space2中有同名方法 需要在引入元素的时候为方法起个别名
    use function  space1add as s;
    
    s();
    add();

    注意:一旦引入的时候使用了别名,那么在使用的时候就直接通过别名使用

    5.如果一个空间有多个元素要引入,那么可以进行一次引入多个使用逗号,分割即可

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    function show(){
    
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    }
    class wuman{
    
    
    }
    
    
    namespace space2;
    
    //一次引入多个空间元素,如class function const 必须分开写
    
    use space1man,space1wuman;         //一次引用2个类
    
    use function space1add,spaceshow;  //一次引入2个函数

    注意:以上方式都是在引入同一种元素,如果要引入多个不同元素,可以如下使用

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    function show(){
        echo __METHOD__;
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    };
    class wuman{
    
    
    }
    
    
    namespace space2;
    
    //一次引入space1的类,函数和常量
    use space1{
        man,
        function add,
        function show,
        const SEX
    };     //注意这个分号是必须的,表示一行结束。
    
    show();

    6.如果说确定一个空间的所有元素都需要引入进来,也可以直接引入空间

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    function show(){
        echo __METHOD__;
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    };
    class wuman{
    
    
    }
    
    
    namespace space2;
    
    //引入空间
    use spcace1;

    注意:如果直接进行空间引入,那么被引入的空间属于当前空间的一个元素,要访问引入空间的其他元素,得从引入空间开始,即引入的空间最后一级空间名字+元素(引入空间当作当前的空间子空间)

    <?php
    
    namespace space1;
    //空间方法
    function add(){
        echo "我是空间add方法";
    }
    function show(){
        echo __METHOD__;
    }
    //空间常量
    const SEX='女';
    //空间类
    class man{
        public $name="小伟";
        public function show(){
            echo $this->name;
        }
    };
    class wuman{
    
    
    }
    
    
    namespace space2;
    
    //引入空间
    use space1;
    //访问被引入空间中的元素
    space1add();

    总结:

      1.空间引入是解决访问时的麻烦,有完全限定名称变成非限定名称访问

      2.空间元素都可以引入,但是引入方式有区别

        类直接引入

        函数需要在use之后添加关键字function

        常量需要在use之后添加关键字const

      3.空间引入过程中如果出现重名,需要使用别名来处理,引入后在空间里可以直接访问别名

      4.可以一次性引入一个空间内的多个元素

      5.如果必须的情况下,也可以直接使用空间引入,但是注意被引入空间的元素不允许直接使用非限定名称访问  

      必须使用被引入空间的最后一级空间+元素访问(不常使用,引入方便但是使用不方便)

    定义

  • 相关阅读:
    NHibernate学习之二
    ETL学习之四:SQL Server Integration Services入门
    NHibernate学习之五:三种常见的配置方法。
    ORACLE执行计划入门
    C# default關鍵字
    WordPress Mail On Update插件跨站请求伪造漏洞
    WordPress Colormix主题多个安全漏洞
    nginx 'ngx_http_parse.c'栈缓冲区溢出漏洞
    Apache HTTP Server日志内终端转义序列命令注入漏洞
    WordPress wpFileManager插件‘path’参数任意文件下载漏洞
  • 原文地址:https://www.cnblogs.com/xiaowie/p/12341227.html
Copyright © 2020-2023  润新知