php的命名空间功能已经出来很久了,但是一直以来没怎么深究过,这次赶着有时间所以特意翻着手册做一个整理和总结帮助自己完善完善,原本准备一篇写完,但发现内容其实还是蛮多的,放一起太长看着累,所以分两篇博客要好些。


一:命名空间概念:命名空间是一种封装事物的方法,类似于目录和文件。

命名空间解决的问题(手册上也写的很清楚,下面按照自己的理解简化了):

1:解决程序编写者自己写的类、常量、函数和php内部的或者第三方的出现名称冲突的情况。

2:创建别名,帮助解决类、常量、函数名称过长的情况,帮助提高代码的可读性,另外名称过长其实通常都是因为为了缓解第一类问题导致的。

二:如何定义命名空间


1:命名空间用关键字namespace声明,同时命名空间必须位于其他代码之前,包括任何非php代码以及空白符(php的declare关键字除外),否则会抛出一个fatal error。

例如:

<?php
namespace Index;
?>

注意1:如果命名空间namespace前没有任何代码及空白符,但还是出现fatal error,这个应该是由于bom头导致的,去掉bom头就可以了。

注意2:在命名空间下,虽然可以放置所有合法的php代码,但是受命名空间影响的仅有类(抽象类以及traits)和接口、常量和函数。

2:与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义,分隔符是\。


例如:

<?php
namespace Index\Col\File;
define('MESSAGE','hello world');
?>


3:一个文件中可以定义多个命名空间,定义的语法有两种,一种是简单组合语法,另一种是大括号形式语法,另外一个文件定义多个命名空间的使用一般是多个文件合并成一个文件的场景,但不到万不得已最好不要这样,因为这样增加了代码的复杂度,可读性会降低,一般情况也没有这种使用的必要。


简单组合语法:

<?php
namespace Index;
const INSTANCE=1;namespace Col;
const INSTANCE=2;
?>

大括号语法,一个文件多个命名空间,如果还需要写上非命名空间的代码,就只能用大括号语法,并且非命名空间代码用namespace声明一个没有名称的命名空间,再用大括号即可:

<?php
/*命名空间Index*/
namespace Index{const INSTANCE=1;
}/*命名空间Col*/
namespace Col{const INSTANCE=2;
}/*全局非命名空间代码*/
namespace {const INSTANCE=3;
}
?>

4:多个不同的文件可以定义同一个命名空间,也就是说同一个命名空间的内容可以分别存储到多个不同的文件中,这里就不举例了。


三:命名空间的识别原理

命名空间的使用原理有三种情况,手册上其实说的详细但可能因为翻译问题导致一些凌乱,这里我简化一下用自己的例子梳理一下:

1:没有限定名称,也就是直接使用要读取的类、常量、函数、接口名称,这种情况会读取该内容所属的命名空间的类、常量、函数、接口名称,但如果命名空间内没有相关的数据,如果是类和接口名称会返回fatal error,如果是函数和常量会自动读取全局的函数和常量,如果全局中也没有,才会报fatal error。

下面举例:

<?php
/*全局非命名空间代码*/
namespace {const INSTANCE=1;function test(){echo 1;}class foo{static function fool(){echo 1;}}var_dump(INSTANCE);  //打印出来的是1test();            //输出1foo::fool();           //输出1}/*命名空间Index*/
namespace Index{const INSTANCE=2;function test(){echo 2;}class foo{static function fool(){echo 2;}}var_dump(INSTANCE);     //打印出来的是2test();        //输出2foo::fool();       //输出2
}/*命名空间Col*/
namespace Col{const INSTANCE=3;function test(){echo 3;}class foo{static function fool(){echo 3;}}var_dump(INSTANCE);   //打印出来的是3test();        //输出3foo::fool();       //输出3
}
?>

上面的例子每个命名空间里输出的都没有限定名称,所以会得到当前命名空间下设置的对应数据值。

如果当前命名空间没有设置,函数和常量则会读取全局设置的对应数据值,全局没有对应的才会报fatal error,类和接口都会直接报fatal error,如下面代码所示。

<?php
/*全局非命名空间代码*/
namespace {const INSTANCE=1;function test(){echo 1;}class foo{static function fool(){echo 1;}}var_dump(INSTANCE);  //打印出来的是1test();        //输出1foo::fool();       //输出1}/*命名空间Index*/
namespace Index{var_dump(INSTANCE);     //打印出来的是1test();        //输出1foo::fool();       //fatal error}
?>

2:限定名称,分为两种情况,一种是包含前缀的限定名称情况,一种是包含全局限定名称的情况。手册上将这两种单独分开了,但我觉得这两种可以合并成一起说,他们都是有限定名称,只是前者没有全局限定,后者有全局限定。

①包含前缀的限定名称,这种前缀可以有多个或者一个层级,但最左侧不能为\全局限定词,这种情况会读取该代码所在命名空间加上该前缀限定名称所对应数据,也就是:

所处命名空间\前缀限定\名称来读取,如果该代码是全局没有命名空间的,则直接用前缀限定名称来读取,也就是:前缀限定\名称来读取。

实例代码:

<?php
/*命名空间Col\Index*/
namespace Col\Index{const INSTANCE=1;
}/*命名空间Index*/
namespace Index{const INSTANCE=2;
}/*命名空间Col*/
namespace Col{const INSTANCE=3;var_dump(Index\INSTANCE); //打印出来的是1 读取的是Col\Index\INSTANCE
}/*全局非命名空间代码*/
namespace {const INSTANCE=4;var_dump(Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE
}?>

②全局限定前缀名称:也就是在最左侧有全局操作符\进行修饰的前缀限定名称,当然也可以没有前缀限定直接全局操作符\加上名称也是可以的。但加上全局操作符后就跟目录里的绝对路径一样,只会按照全局限定后的所设置的进行读取。

具体实例如下:

<?php
/*命名空间Col\Index*/
namespace Col\Index{const INSTANCE=1;
}/*命名空间Index*/
namespace Index{const INSTANCE=2;
}/*命名空间Col*/
namespace Col{const INSTANCE=3;var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE
}/*全局非命名空间代码*/
namespace {const INSTANCE=4;var_dump(\Index\INSTANCE); //打印出来的是2 读取的是Index\INSTANCE
}namespace Lin{const INSTANCE=5;var_dump(\INSTANCE); //打印出来的是4 读取的是INSTANCE,是全局非命名空间里的INSTANCE,如果没有全局操作符\,读取的会是当前命名空间的Lin\INSTANCE=5
}?>

四:命名空间在字符串中的转义


有时候命名空间会放在字符串中使用,如果是单引号不会通过编译器解释,所以没有任何问题,但是如果是双引号,那么就会有些意外情况了,要知道双引号里的内容是需要经过编译器进行解释然后再进行输出的,而\在编译器里的解释容易造成歧义

例如"index\name"这里就有\n会被解释成换行,除此之外还有很多这种造成意外的情况。

因此一般我们推荐命名空间如果要放在字符串中使用,最好使用单引号,一是效率,二是安全,如果使用双引号,则必须增加一个\进行转义避免歧义,例如"index\\name"这样就没有问题了。

随手双引号的举个例子:

<?php
/*全局非命名空间代码*/
namespace Index\Name{class foo{function __construct(){echo 2;}}
}namespace{$a= "Index\\Name\\foo"; //用\转义了\所以可以正常运行,但是如果去掉转义的话会报错Class 'Index\Nameoo',因为/f被解释成了换页符$obj=new $a;
}

这部分碍于篇幅就暂时到这里了,下一篇主要总结命名空间里的namespace和__NAMESPACE__的使用,以及别名的使用等,另外改版后怎么觉得编辑器更差了,明明排好版,放上来都是乱七八糟,还不如不排版。


详细解读php的命名空间(一)相关推荐

  1. 详细解读Maven中pom.xml

    详细解读Maven中pom.xml 一.POM是什么 二.存放位置 三.基本设置 3.1.头信息 3.2.maven的基本信息 3.3.POM之间的关系 3.3.1.依赖关系 3.3.2 继承关系:继 ...

  2. NLP突破性成果 BERT 模型详细解读 bert参数微调

    https://zhuanlan.zhihu.com/p/46997268 NLP突破性成果 BERT 模型详细解读 章鱼小丸子 不懂算法的产品经理不是好的程序员 ​关注她 82 人赞了该文章 Goo ...

  3. VINS-mono详细解读与实现

    VINS-mono详细解读 VINS-mono详细解读 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/V ...

  4. R回归模型输出结果详细解读:summary、call、residuals、Coefficients、Assessing Model Fit

    R回归模型输出结果详细解读:summary.call.residuals.Coefficients.Assessing Model Fit 目录 R回归模型输出结果详细解读:summary.call. ...

  5. MemCache超详细解读

    MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...

  6. CSS 详细解读定位属性 position 以及参数

    Css 详细解读定位属性 position 以及参数 position 定位属性,是CSS中非常重要的属性.除了文档流布局,就是定位布局了.本来我对这个问题没有放在心上,毕竟写了这么多年的css,对p ...

  7. MemCache详细解读

    MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...

  8. 直播 | 腾讯天衍实验室张子恒:详细解读天衍实验室知识图谱对齐技术

    「AI Drive」是由 PaperWeekly 和 biendata 共同发起的学术直播间,旨在帮助更多的青年学者宣传其最新科研成果.我们一直认为,单向地输出知识并不是一个最好的方式,而有效地反馈和 ...

  9. Madgwick算法详细解读

    Madgwick算法详细解读 极品巧克力 前言 接上一篇文章<Google Cardboard的九轴融合算法>. Madgwick算法是另外一种九轴融合的方法,广泛应用在旋翼飞行器上,效果 ...

  10. Transformer详细解读与预测实例记录

    文章目录 Transformer详细解读与预测实例记录 1.位置编码 1)输入部分: 2)位置编码部分: 2.多头注意力机制 1)基本注意力机制 2)transformer中的注意力 3.残差和Lay ...

最新文章

  1. 案例精解企业网络构建读书笔记之网络故障排除案例
  2. Kali Linux Web 渗透测试— 第十二课-websploit
  3. curl 与 header 及 file_get_countents 访问内容时的区别
  4. 【控制】《多智能体系统一致性协同演化控制理论与技术》纪良浩老师-第6章-一阶时滞多智能体系统分组一致性
  5. Xcode 8带来的新特性和坑
  6. Elasticsearch的倒排索引是什么?
  7. java treemap value排序_【TreeMap】对Map按key和value分别排序
  8. Linux忘记root密码
  9. iphone mac地址是否随机_iPad 的 Mac 地址是否会随机更换,如何关闭呢
  10. 对python几个常见的小函数进行学习使用
  11. Lua1.0 数据结构
  12. win10 专业版 explorer.exe下载 (完全Free)
  13. 在线支付功能实现代码
  14. Shaolin - HDU 4585 - 树堆
  15. ArcGIS 移动、旋转、比例缩放、复制工具
  16. 使用hexo+gitee免费搭建个人博客全网最详细
  17. 股票量化分析(11)——第二个策略(5日移动均线、双均线、MACD策略)
  18. Jboot整合Swagger
  19. 学校教室计算机室云课堂软件,专注云教室教育培训云课堂的NC个人云桌面
  20. HTTP协议-get与post请求

热门文章

  1. jupyter notebook 内核似乎挂掉了
  2. 网站木马检测_网站建立检测劫持,网站建立检测劫持如何操作,详细步骤
  3. eclipse工程图标上有个红色感叹号
  4. TTF、TOF、WOFF 和 WOFF2 的相关概念
  5. SolidWorks用鼠标中键控制模型的旋转、缩放和平移
  6. Delphi 金额转大写
  7. (Matlab)复现《改进NSGA_II算法求解考虑运输约束的柔性作业车间节能调度问题》中的交叉操作
  8. Calibre转换电子书格式
  9. 在有C语言的基础上,快速学习python(C语言转战python)(python3)
  10. 2.reflect.TypeOf()