php进阶之路 -- 03 命名空间

  1. 命名空间概述
  2. 定义命名空间
  3. 空间成员和子空间
  4. 空间成员的访问
  5. 空间引入
  6. 全局空间   

一、 命名空间概述

  什么是命名空间?从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。具体举个例子,文件 foo.txt 可以同时在目录/home/greg 和 /home/other 中存在,但在同一个目录中不能存在两个 foo.txt 文件。另外,在目录 /home/greg 外访问 foo.txt 文件时,我们必须将目录名以及目录分隔符放在文件名之前得到 /home/greg/foo.txt。这个原理应用到程序设计领域就是命名空间的概念。

  在PHP中,命名空间用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

    ①用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。

    ②为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

二、定义命名空间

  命名空间在实际开发中的作用是非常大的,那么想要使用命名空间需要通过namespace关键字:

 <?php
/**
* Created by PhpStorm.
* User: liujunhang
* Date: 2018/6/18
* Time: 12:11
*/ namespace ONE; class MyClass1{ public function say(){
echo __NAMESPACE__;
}
}
$obj = new MyClass1(); namespace TWO;
class MyClass1 {
public function say(){
echo __NAMESPACE__;
}
}
$obj = new MyClass1();

  上面代码中,我们在同一个文件中创建了两个相同类名的类,但是代码并没有报错,原因是因为我们开启了两个命名空间,相当于在两篇内存地址中,并不冲突。

  那么在使用命名空间时有以下需要注意的点:

  1. 如果一个脚本定义命名空间,那么必须写在有效代码的第一行。
  2. 在同一个文件中,可以使用魔术常量__NAMESPACE__来查看当前的命名空间。
  3. 一个脚本周期内,可以定义多个命名空间,并且不同的空间可以定义相同的函数、常量和类。

  不同的命名空间当中,所有的内容并不会冲突和干扰。

下面的例子中存在着一种特殊情况:

原因:变量不属于空间成员。

三、空间成员和子空间

空间成员  

首先,一个命名的空间内,可以有任何的php代码。但是命名空间本身只负责三种类型:常量、函数、类。其他的都不属于空间成员。

上面代码的运行结果是:

所以说,命名空间内,除了使用空间成员(类、函数和常量)受命名空间的限制之外,其他的代码都是该怎么执行就怎么执行,跟不存在命名空间一样。

子空间  

  同我们计算机可以存在子目录一样,内存中也同样可以存在子空间。

例如:

  目录:A/B/C ,其中C就是B的子目录,B就是A的子目录。

  空间:namespace A\B\C,其中C就是B的子空间,B就是A的子空间。注意使用反斜杠\,其表示的含义是创建了一个名为C的子空间,并且A和B空间也一起创建了。

例如:

进入B空间可以如下:

思考:我们能不能够在B空间中访问其子空间C的成员呢?

  上面的问题不能访问的原因:所谓的父子空间只是逻辑上的划分,实际上还是处在不同的空间当中,所以并不能直接进行访问。

  那么我们如何在不同的空间中进行访问呢?

四、空间成员的访问

如何在众多的命名空间中如何访问某个空间中的某个成员。

php中提供了三种访问空间成员的方式:

  非限定名称访问

  限定名称访问

  完全限定名称访问

非限定名称访问

  所谓的非限定名称访问,就是非指定名称访问,就是在访问空间成员的时候,没有指定具体的空间的名字,到目前为止,我们前面使用的所有的访问方式都属于非限定名称访问。

  

那么上面这种访问方式缺点是什么呢?

例如我们之前写过的实例,当我们在某个空间中直接访问(采用非限定名称访问)另外一个空间的常量时,系统就会提示我们未找到。

那么很显然,非限定名称访问,只能访问到当前所属的空间,所谓的当前所属的空间,就是当前代码向下寻找的第一个空间,存在即访问,不存在就报错。

限定名称的访问

  所谓的限定名称的访问,就是从当前名称开始访问其子空间的成员。

语法形式为:

  子空间名\空间成员名

  我们回到上面的问题,想要从B里访问到C中的内容。可以如下:

完全限定名称访问

  所谓的完全限定名称访问,就是直接从根空间(类比根目录)开始对绝对的路径的访问!

语法形式:

  \空间1\空间2\......    其中的反斜杠代的是根路径

例如:

所以,采用完全限定名称访问的最大好处是可以在任意的空间访问其他任意空间的成员。

五、空间引入

概念:

当一个脚本包含了另外一个脚本,就出现了空间引入的问题。

例如我们下面碰到的问题:

t1.php

t2.php

此时我们的问题是,t1.php中的getName()方法调用,输出结果为什么?

是HELLO,还是WORLD?

结果为什么为HELLO,而不是WORLD呢?why?

按照我们的理解,在调用getName()方法之前我们明明就已经把t2.php引入进t1.php中,那么相当于getName调用的应该是t2里面的getName()方法。

原因:

出现这种情况是由于加载机制导致的。

因为文件的载入是发生在代码的执行阶段,而不是预编译阶段。

所以此时的getName()调用其实还是属于HELLO空间内,所以还是调用的是HELLO空间内的getName()方法。

思考:

如何访问加载进来的WORLD空间的成员?

首先,不能使用非限定名称访问,因为非限定名称访问只能访问其默认的上级空间(刚才例子中getNamef()调用访问的默认的上级空间HELLO)。

其次,也不能使用限定空间名称访问,因为限定空间名称访问只能访问当前的子空间成员。除非被引入的空间是当前空间的子空间!

而如果想要使用WORLD空间的getName方法,可以使用完全限定名称访问。

空间类的引入  

所谓的空间类的引入,就是把其他的空间的类引入到当前的空间,在当前的空间直接使用这个类。

具体实现方式主要是通过use的形式来进行实现。

如下:

通过use关键字我们成功的使用了另外一个空间,但是还有一个问题,如果引入的空间中的类与本空间中的类相同,例如下面:

如果真的存在上面的情况,那么代码就会报错,那么该如何解决呢?

解决方案如下:

六、 全局空间

概念

如果不给脚本定义命名空间,那么脚本中定义的内容就属于全局空间。

例如:

按照我们之前的逻辑如果想要使用这个文件,需要引入这个文件 ,如下:

我们可以尝试下面的解决方案:

php进阶之路 -- 03 命名空间的更多相关文章

  1. 处女作《Web全栈开发进阶之路》出版了!

    书中源码下载地址:https://github.com/qinggee/WebAdvanced 01. 当初决定写博客的原因非常的纯洁:只要每个月写上 4 篇以上博客,月底的绩效奖金就多 500 块. ...

  2. GO语言的进阶之路-初探GO语言

    GO语言的进阶之路-初探GO语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么我们需要一门新语言 Go语言官方自称,之所以开发Go 语言,是因为“近10年来开发程序之难 ...

  3. GO语言的进阶之路-协程和Channel

    GO语言的进阶之路-协程和Channel 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 看过我之前几篇博客小伙伴可能对Golang语言的语法上了解的差不多了,但是,如果想要你的代码 ...

  4. GO语言的进阶之路-面向对象编程

    GO语言的进阶之路-面向对象编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 当你看完这篇文章之时,我可以说你的Golang算是入门了,何为入门?就是你去看Docker 源码能看 ...

  5. JavaScript进阶之路(一)初学者的开始

    一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...

  6. OpenCV进阶之路:神经网络识别车牌字符

    1. 关于OpenCV进阶之路 前段时间写过一些关于OpenCV基础知识方面的系列文章,主要内容是面向OpenCV初学者,介绍OpenCV中一些常用的函数的接口和调用方法,相关的内容在OpenCV的手 ...

  7. MVC进阶之路:依赖注入(Di)和Ninject

    MVC进阶之路:依赖注入(Di)和Ninject 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类, ...

  8. 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)

    [SSH进阶之路]Hibernate基本原理(一) ,小编介绍了Hibernate的基本原理以及它的核心,採用对象化的思维操作关系型数据库. [SSH进阶之路]Hibernate搭建开发环境+简单实例 ...

  9. 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)

    文件夹      [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器開始(八)      [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入 ...

随机推荐

  1. Python标准库: turtle--海龟绘图。

    turtle --- 海龟绘图 (点击查看官方文档.) 简介 import turtle # 调用该库.Turtle的实例对象,默认命名为turtle. turtle.forward(10) from ...

  2. HNOI2004 树的计数 和 HNOI2008 明明的烦恼

    树的计数 输入文件第一行是一个正整数n,表示树有n个结点.第二行有n个数,第i个数表示di,即树的第i个结点的度数.其中1<=n<=150,输入数据保证满足条件的树不超过10^17个. 明 ...

  3. 消金ABS

    对于持牌消金公司来说,发行ABS需满足至少3年经营期限的硬性规定,目前已开业的24家消金公司里,有15家符合此项规定. 2019年下半年以来,个人消费金融领域共发行了15个资产证券化产品,发行规模达4 ...

  4. hive传递参数与调用

    在运行hive命令时传入参数,使用-hivevar 和 -hiveconf 两种参数选项,来给此次的执行脚本传入参数 -hivevar : 传参数 ,专门提供给用户自定义变量. -hiveconf : ...

  5. jquery实现在光标位置(input、textarea)插入内容的方法

    通过扫码枪扫码.按钮点击事件在光标处插入文本,这是前台js常用的功能.但是在input输入框和textarea文本框定位光标,插入数据是有点不同的 首先最简单的,适用于input输入框的方法 HTML ...

  6. apache log4j将日志保存在mongodb数据库中(转)

    og4j与mongodb整合 Mongo Java driver jar包 log4mongo-java jar包 配置log4j.properties文件,使之整合mongodb: #将Mongod ...

  7. 漫话:什么是 https ?这应该是全网把 https 讲的最好的一篇文章了

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/m0_37907797/article/d ...

  8. HDU 5726 GCD (2016多校、二分、ST表处理区间GCD、数学)

    题目链接 题意 : 给出一个有 N 个数字的整数数列.给出 Q 个问询.每次问询给出一个区间.用 ( L.R ) 表示.要你统计这个整数数列所有的子区间中有多少个和 GCD( L ~ R ) 相等.输 ...

  9. sh_14_字符串定义和遍历

    sh_14_字符串定义和遍历 str1 = "hello python" str2 = '我的外号是"大西瓜"' print(str2) print(str1[ ...

  10. 面试题:MySQL索引为什么用B+树?

    面试题:MySQL索引为什么用B+树? 前言 讲到索引,第一反应肯定是能提高查询效率.例如书的目录,想要查找某一章节,会先从目录中定位.如果没有目录,那么就需要将所有内容都看一遍才能找到. 索引的设计 ...