PHP进阶学习之命名空间基本用法分析


Posted in PHP onJune 18, 2019

本文实例讲述了PHP进阶学习之命名空间基本用法。分享给大家供大家参考,具体如下:

前言

命名空间(namespace),在编程语言中,是对作用域的一种特殊的抽象.它表示着一个标识符的可见范围。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他命名空间中。

在PHP中也存在命名空间的用法,由它控制可见范围的这个标识符一般指的就是类和函数。

一、PHP命名空间基础

从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如PHP的类名是不可以重复的,但是经常我们需要引入一些第三方的类库,常常类名就会在项目中产生重复冲突,所以,命名空间就是解决这个冲突的一种方法。

在PHP5.3以后,就已经引入了命名空间(namespace)的概念,即同个命名空间下的类名不能重复,不同命名空间下可以存在同名的类。

这样,在引入第三方类库的时候,只有各个类库的命名空间不一样,就不会产生冲突。

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

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

需要注意的是:

  • 同个文件下可以存在多个命名空间;
  • 不同命名空间内的类可以相互调用。

PHP进阶学习之命名空间基本用法分析

二、PHP命名空间的用法

1、定义

命名空间的定义采用关键字namespace,定义方式如下:

namespace example

则该命名空间下的类都归属于该命名空间,example命名空间下的类不能重名。

或者可以定义多级命名空间:

namespace example\test\demo

则改命名空间下的类全归属于example\test\demo命名空间。

定义后的命名空间可以用_​_​NAMESPACE_​_​魔法变量来获取当前命名空间。

2、引入

引入命名空间使用关键字use,可以通过多个use在一个文件中引入多个命名空间:

use example;
use example\test\demo;

需要使用到哪个命名空间的类和方法,则use哪个命名空间,前提是这些命名空间的实际文件地址已经包含进来了,或者说能实现自动的类加载了。

3、实例化

在程序中实例化并使用某个命名空间下的类方法,同样使用new关键字进行实例化,但是需要在类名前面加上命名空间前缀。

例如:

$class = new example\a();//实例化example命名空间下的a类
$class = new example\test\demo\b(); //实例化example\test\demo命名空间下的b类

如果在文件前面已经引入了这些命名空间,则可以不需要类的前缀:

use example;
use example\test\demo;
$class = new a();//实例化example命名空间下的a类
$class = new b(); //实例化example\test\demo命名空间下的b类

注:如果use的时候是use example\test;则在实例化b类时要带上相对命名空间路径(注意不是实际文件路径),即new demo\b();

当然所有的实例化都可以直接使用绝对路径形式,即在命名空间前面加\字符,如new \example\test\demo\b();这样就采用了绝对路径形式实例化了b类。

4、别名

在用namespace定义命名空间的时候,为了避免之后引用的时候命名空间过长,可以在定义时采用as关键字为一个命名空间指定别名

namespace example\test\demo as testDemo;

这样在之后引用或实例化的时候就可以new testDemo\<类名>();

三、基于PSR4的命名空间规范

由于方法、类在不同项目中命名空间定义不一致,第三方类库的命名空间也定义不一致,所以相关php组织出台了一套约定俗成的规范,即PSR4规范,

用来规范命名空间的定义规则。

具体规范如下:

1. 一个完整的类名需具有以下结构:

\<命名空间>(\<子命名空间>)*\<类名>
    1. 完整的类名 必须 要有一个顶级命名空间,被称为 "vendor namespace";
    2. 完整的类名 可以 有一个或多个子命名空间;
    3. 完整的类名 必须 有一个最终的类名;
    4. 完整的类名中任意一部分中的下滑线都是没有特殊含义的;
    5. 完整的类名 可以 由任意大小写字母组成;
    6. 所有类名都 必须 是大小写敏感的。

2. 当根据完整的类名载入相应的文件

    (1). 完整的类名中,去掉最前面的命名空间分隔符,前面连续的一个或多个命名空间和子命名空间,作为「命名空间前缀」,其必须与至少一个「文件基目录」相对应;
    (2). 紧接命名空间前缀后的子命名空间 必须 与相应的「文件基目录」相匹配,其中的命名空间分隔符将作为目录分隔符。
    (3). 末尾的类名 必须 与对应的以 .php 为后缀的文件同名。
    (4). 自动加载器(autoloader)的实现 一定不可 抛出异常、一定不可 触发任一级别的错误信息以及 不应该 有返回值。

看起来很复杂,其实规范的要点就是,命名空间的路径要与当前文件的路径相对应,这样规范了所有项目命名空间的定义准则,虽然PHP官方没有

强制规定,但如今许多开源项目都已经约定俗成地使用了,这种规范便于查找命名空间下的类所在的路径。

例如,文件目录a/b/c下有d.php,则在a目录下的的文件引入d的类时,应该是use b/c或use /a/b/c;(绝对路径形式)

四、注意点

1、代码复用类Trait也符合命名空间的规范,即通过命名空间下Trait类不能重名;
2、虽然PSR4规定了命名空间路径与文件路径需要相对应,但是运行php时命名空间路径与文件路径是没有任何关系的,例如a/b/c下的文件类d,命名空间可以写成a1/b1/c1/d;只不过现在的许多开源框架在实现类自动加载的时候把两者规范为一致,否则会出现类文件加载到了,但是命名空间却加载不到的情况。
3、在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间A\B内部调用C\D\e(),则C\D\e()会被转换为A\B\C\D\e()。
4、在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数foo()的调用是这样解析的:
(1)在当前命名空间中查找名为A\B\foo()的函数
(2)尝试查找并调用全局(global)空间中的函数foo()。
5、在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用new C()及new D\E()的解析过程:new C()的解析:
(1)在当前命名空间中查找A\B\C类。
(2)尝试自动装载类A\B\C。

以上内容引用了PSR4文档地址:http://www.php-fig.org/psr/psr-4/

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

PHP 相关文章推荐
PHP.MVC的模板标签系统(一)
Sep 05 PHP
快速开发一个PHP扩展图文教程
Dec 12 PHP
php中防止伪造跨站请求的小招式
Sep 02 PHP
php检测文件编码的方法示例
Apr 25 PHP
php生成短网址示例
May 05 PHP
PHP定时任务延缓执行的实现
Oct 08 PHP
Zend Guard使用指南及问题处理
Jan 07 PHP
php单一接口的实现方法
Jun 20 PHP
详解HTTP Cookie状态管理机制
Jan 14 PHP
PHP微信H5支付开发实例
Jul 25 PHP
浅谈PHPANALYSIS提取关键字
Mar 08 PHP
详解PHP神奇又有用的Trait
Mar 25 PHP
PHP进阶学习之反射基本概念与用法分析
Jun 18 #PHP
Laravel使用RabbitMQ的方法示例
Jun 18 #PHP
thinkphp整合系列之极验滑动验证码geetest功能
Jun 18 #PHP
PHP Trait代码复用类与多继承实现方法详解
Jun 17 #PHP
php设计模式之装饰模式应用案例详解
Jun 17 #PHP
php设计模式之策略模式应用案例详解
Jun 17 #PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
Jun 17 #PHP
You might like
php 在文件指定行插入数据的代码
2010/05/08 PHP
php-fpm配置详解
2014/02/12 PHP
php调用mysql存储过程实例分析
2014/12/29 PHP
php实现上传图片文件代码
2015/07/19 PHP
Zend Framework分发器用法示例
2016/12/11 PHP
详解thinkphp实现excel数据的导入导出(附完整案例)
2016/12/29 PHP
PHP删除数组中特定元素的两种方法
2019/02/28 PHP
基于jQuery图片平滑连续滚动插件
2009/04/27 Javascript
js cookies实现简单统计访问次数
2009/11/24 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
javascript实现带下拉子菜单的导航菜单效果
2015/05/14 Javascript
详解JavaScript逻辑Not运算符
2015/12/04 Javascript
限制文本框只能输入数字||只能是数字和小数点||只能是整数和浮点数
2016/05/27 Javascript
jQuery插件zTree实现更新根节点中第i个节点名称的方法示例
2017/03/08 Javascript
angularjs实现简单的购物车功能
2017/09/21 Javascript
node使用Koa2搭建web项目的方法
2017/10/17 Javascript
nodejs判断文件、文件夹是否存在及删除的方法
2017/11/10 NodeJs
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
基于Web Audio API实现音频可视化效果
2020/06/12 Javascript
vue实现虚拟列表功能的代码
2020/07/28 Javascript
深入浅析python with语句简介
2018/04/11 Python
Python使用selenium实现网页用户名 密码 验证码自动登录功能
2018/05/16 Python
利用python打开摄像头及颜色检测方法
2018/08/03 Python
python获取本机所有IP地址的方法
2018/12/26 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
Matplotlib自定义坐标轴刻度的实现示例
2020/06/18 Python
TensorFlow的环境配置与安装方法
2021/02/20 Python
html5清空画布方法(三种)
2017/10/16 HTML / CSS
经济实惠的豪华背包和行李袋:Packs Project
2018/10/17 全球购物
美国翻新电子产品商店:The Store
2019/10/08 全球购物
计算机学生求职信范文
2014/01/30 职场文书
工地安全生产标语
2014/06/06 职场文书
中学教师读书笔记
2015/07/01 职场文书
交流会主持词
2015/07/02 职场文书
Python编写冷笑话生成器
2022/04/20 Python
搭建Yolov5服务器
2022/04/30 Servers