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解析html的实现代码
Aug 08 PHP
PHP取进制余数函数代码
Jan 19 PHP
php empty()与isset()区别的详细介绍
Jun 17 PHP
php selectradio和checkbox默认选择的实现方法详解
Jun 29 PHP
php生成短网址示例
May 05 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
php中file_exists函数使用详解
May 08 PHP
php数组比较实现查找连续数的方法
Jul 29 PHP
thinkphp3.2点击刷新生成验证码
Feb 16 PHP
php生成验证码,缩略图及水印图的类分享
Apr 07 PHP
ThinkPHP中Common/common.php文件常用函数功能分析
May 20 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
Mar 27 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 中TP5 Request 请求对象的实例详解
2017/07/31 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
2019/02/20 PHP
laravel-admin 管理平台获取当前登陆用户信息的例子
2019/10/08 PHP
php5与php7的区别点总结
2019/10/11 PHP
javascript Demo模态窗口
2009/12/06 Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
2015/03/04 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
如何用JavaScript实现动态修改CSS样式表
2016/05/20 Javascript
js实现随机点名小功能
2017/08/17 Javascript
JS模拟超市简易收银台小程序代码解析
2017/08/18 Javascript
node简单实现一个更改头像功能的示例
2017/12/29 Javascript
JavaScript 日期时间选择器一些小结
2018/04/02 Javascript
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】
2018/05/26 jQuery
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
jquery简单实现纵向的无缝滚动代码实例
2019/04/01 jQuery
layui实现数据分页功能(ajax异步)
2019/07/27 Javascript
微信小程序实现简单文字跑马灯
2020/05/26 Javascript
区分vue-router的hash和history模式
2020/10/03 Javascript
vuex页面刷新导致数据丢失的解决方案
2020/12/10 Vue.js
[38:30]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场2
2014/05/24 DOTA
[01:27:43]VGJ.S vs TNC Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
详解python使用Nginx和uWSGI来运行Python应用
2018/01/09 Python
Python之列表实现栈的工作功能
2019/01/28 Python
python实现从wind导入数据
2019/12/03 Python
详解Django关于StreamingHttpResponse与FileResponse文件下载的最优方法
2021/01/07 Python
使paramiko库执行命令时在给定的时间强制退出功能的实现
2021/03/03 Python
Amara德国:家居饰品、设计师品牌和豪华礼品
2019/05/20 全球购物
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
Yahoo-PHP面试题4
2012/05/05 面试题
数控技术专科生自我评价
2014/01/08 职场文书
党的群众路线教育实践活动心得体会
2014/03/03 职场文书
2015年个人招商工作总结
2015/04/25 职场文书
正规借条模板
2015/05/26 职场文书
python自动统计zabbix系统监控覆盖率的示例代码
2021/04/03 Python
python3读取文件指定行的三种方法
2021/05/24 Python
为Centos安装指定版本的Docker
2022/04/01 Servers