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网站安装程序制作的原理、步骤、注意事项和示例代码
Aug 01 PHP
php在文件指定行中写入代码的方法
May 23 PHP
Linux下手动编译安装PHP扩展的例子分享
Jul 15 PHP
PHP正则表达式 /i, /is, /s, /isU等介绍
Oct 23 PHP
php实现两个数组相加的方法
Feb 17 PHP
PHP的Yii框架的基本使用示例
Aug 21 PHP
thinkphp5 URL和路由的功能详解与实例
Dec 26 PHP
PHP程序员学习使用Swoole的理由
Jun 24 PHP
PHP后台实现微信小程序登录
Aug 03 PHP
微信小程序发送订阅消息的方法(php 为例)
Oct 30 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 PHP
php去除deprecated的实例方法
Nov 17 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封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
2014/06/19 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
2019/03/18 PHP
在phpstudy集成环境下的nginx服务器下配置url重写
2019/12/02 PHP
JS处理VBArray的函数使用说明
2008/05/11 Javascript
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
js中如何把字符串转化为对象、数组示例代码
2013/07/17 Javascript
关于Jquery操作Cookie取值错误的解决方法
2013/08/26 Javascript
node.js中的console.warn方法使用说明
2014/12/09 Javascript
js实现的倒计时按钮实例
2015/06/24 Javascript
理解js对象继承的N种模式
2016/01/25 Javascript
jquery ui dialog替代confirm实例分析
2016/01/25 Javascript
JQuery 两种方法解决刚创建的元素遍历不到的问题
2016/04/13 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
详解Angularjs在控制器(controller.js)中使用过滤器($filter)格式化日期/时间实例
2017/02/17 Javascript
利用js编写网页进度条效果
2017/10/08 Javascript
禁止弹窗中蒙层底部页面跟随滚动的几种方法
2017/12/07 Javascript
让你5分钟掌握9个JavaScript小技巧
2018/06/09 Javascript
Vue.js 2.x之组件的定义和注册图文详解
2018/06/19 Javascript
js中数组对象去重的两种方法
2019/01/18 Javascript
JS去除字符串最后的逗号实例分析【四种方法】
2019/06/20 Javascript
jquery获取input输入框中的值
2019/11/13 jQuery
简单介绍Python下自己编写web框架的一些要点
2015/04/29 Python
Python函数式编程指南(二):从函数开始
2015/06/24 Python
Django model反向关联名称的方法
2018/12/15 Python
Django框架基础模板标签与filter使用方法详解
2019/07/23 Python
在Python中画图(基于Jupyter notebook的魔法函数)
2019/10/28 Python
python标识符命名规范原理解析
2020/01/10 Python
Python中join()函数多种操作代码实例
2020/01/13 Python
什么是python的函数体
2020/06/19 Python
Python项目实战之使用Django框架实现支付宝付款功能
2021/02/23 Python
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
印度低票价航空公司:GoAir
2017/10/11 全球购物
小学生美德少年事迹
2014/02/02 职场文书
ktv筹备计划书
2014/05/03 职场文书
艺术设计专业求职自荐信
2014/05/19 职场文书
高三教师工作总结2015
2015/07/21 职场文书