如何理解PHP核心特性命名空间


Posted in PHP onMay 28, 2021

提出

PHP 在 5.3 后提出了命名空间用来解决组件之间的命名冲突问题,主要参考了文件系统的设计:

  • 同一个目录下不允许有相同的文件名 - 同一个命名空间下不允许有相同的类;
  • 不同的目录可以有同名文件 - 不同的命名空间可以有相同的类;

定义

使用namespace关键字来定义一个命名空间。其中,顶层命名空间通常为厂商名,不同开发者的厂商命名空间是唯一的。命名空间不需要与文件目录一一对应,但是最好遵守PSR-4规范。

<?php

namespace Symfony\Component\HttpFoundation;

class Request {

}
命名空间必须在所有代码之前声明,唯一的例外就是 declare 关键字。

<?php

declare(strict_types=1);

namespace App;

命名空间内可包含任意 PHP 代码,但是仅对类 (包括抽象类和 Trait)、接口、函数和常量这四种类型生效。

<?php
namespace MyProject;

const CONNECT_OK = 1;
class FOO {}
interface Foo{}
function foo() {}

使用

使用use关键字来引入命名空间

<?php

namespace App;

use Symfony\Component\HttpFoundation\Request;
use Foo\Bar;

class Test {
    public function run()
    {
        $bar = new Bar();
    }
}

定义和使用推荐遵循PSR-2的规范

  • namespace之后必须存在一个空行;
  • 所有use声明必须位于namespace声明之后;
  • 每条use声明必须只有一个use关键字。

use语句块之后必须存在一个空行。

当use引入的类出现同名时,可使用as来定义别名

<?php

namespace App;

use Foo\Bar as BaseBar;

class Bar extends BaseBar {

}

限定符

除了使用use外,还可以直接使用\限定符来进行解析,规则很简单:如果含有\前缀则代表从全局命名空间开始解析,否则则代表从当前命名空间开始解析。

<?php

namespace App;

\Foo\Bar\foo();  // 解析成 \Foo\Bar\foo();
Foo\Bar\foo();  // 解析成 App\Foo\Bar\foo();
此规则也适用于函数、常量等

$a = \strlen('hi'); // 调用全局函数 strlen
$b = \INI_ALL; // 访问全局常量 INI_ALL
$c = new \Exception('error'); // 实例化全局类 Exception

有两个需要特别注意的地方:

对于函数和常量而言,如果当前命名空间不存在,则会自动去全局命名空间去寻找,因此可省略\前缀。对于类而言,如果当前命名空间解析不到,不会去全局空间寻找,因此,不可省略\

$a = strlen('hi');
$b = INI_ALL;
$c = new Exception('error'); // 错误
$c = new \Exception('error'); // 正确

当动态调用命名空间时,该命名空间始终会被当成是全局命名空间,因此可以省略前缀\

$class1 = 'Foo\Bar';
$object1 = new $class1;  // 始终被解析成 \Foo\Bar

在内部访问命名空间

PHP 支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__魔术常量和namespace关键字。

__NAMESPACE__常量的值是包含当前命名空间名称的字符串,如果是在全局命名空间,则返回空字符串。

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}

关键字namespace可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的self操作符

namespace App;

use blah\blah as mine;

blah\mine(); // App\blah\mine()
namespace\blah\mine(); // App\blah\mine()

namespace\func(); // App\func()
namespace\sub\func(); // App\sub\func()
namespace\cname::method(); // App\cname::method()
$a = new namespace\sub\cname(); // App\sub\cname
$b = namespace\CONSTANT; // App\CONSTANT

转义\符号

此外,推荐对所有的\进行转义,避免出现不可预期的后果

$class = "dangerous\name"; // \n 被解析成换行符
$obj = new $class;

$class = 'dangerous\name'; // 正确,但是不推荐
$class = 'dangerous\\name'; // 推荐
$class = "dangerous\\name"; // 推荐

以上就是如何理解PHP核心特性命名空间的详细内容,更多关于PHP命名空间的资料请关注三水点靠木其它相关文章!

PHP 相关文章推荐
php 自写函数代码 获取关键字 去超链接
Feb 08 PHP
PHP学习笔记之二
Jan 17 PHP
Yii操作数据库的3种方法
Mar 11 PHP
php判断输入是否是纯数字,英文,汉字的方法
Mar 05 PHP
PHP模拟登陆163邮箱发邮件及获取通讯录列表的方法
Mar 07 PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 PHP
php mailer类调用远程SMTP服务器发送邮件实现方法
Mar 04 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
Jul 09 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
Feb 23 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
Jun 30 PHP
PHP面向对象五大原则之依赖倒置原则(DIP)详解
Apr 08 PHP
PHP mkdir创建文件夹实现方法解析
Nov 13 PHP
如何用Laravel包含你自己的帮助函数
May 27 #PHP
详解Laravel框架的依赖注入功能
May 27 #PHP
详解PHP Swoole与TCP三次握手
May 27 #PHP
如何用PHP实现分布算法之一致性哈希算法
如何用PHP实现多线程编程
May 26 #PHP
如何用PHP websocket实现网页实时聊天
详解PHP用mb_string处理windows中文字符
May 26 #PHP
You might like
php 无限级数据JSON格式及JS解析
2010/07/17 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
2013/07/03 PHP
PHP面向对象程序设计中的self、static、parent关键字用法分析
2019/08/14 PHP
ArrayList类(增强版)
2007/04/04 Javascript
JQuery Easyui Tree的oncheck事件实现代码
2010/05/28 Javascript
JS获取地址栏参数的几种方法小结
2014/02/28 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
SuperSlide2实现图片滚动特效
2014/06/20 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
JavaScript实现俄罗斯方块游戏过程分析及源码分享
2015/03/23 Javascript
js实现仿网易点击弹出提示同时背景变暗效果
2015/08/13 Javascript
详细分析Javascript中创建对象的四种方式
2016/08/17 Javascript
JS实现微信里判断页面是否被分享成功的方法
2017/06/06 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
Vuex实现数据共享的方法
2019/12/20 Javascript
详细探究Python中的字典容器
2015/04/14 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
Ubuntu18.04中Python2.7与Python3.6环境切换
2019/06/14 Python
基于TensorFlow中自定义梯度的2种方式
2020/02/04 Python
anaconda升级sklearn版本的实现方法
2021/02/22 Python
html5 利用canvas实现超级玛丽简单动画
2013/09/06 HTML / CSS
HTML5微信播放全屏问题的解决方法
2017/03/09 HTML / CSS
美国女性卫生用品公司:Thinx
2017/06/30 全球购物
EMPHASIS艾斐诗官网:周生生旗下原创精品珠宝品牌
2020/12/17 全球购物
C#中的验证控件有几种
2014/03/08 面试题
25道Java面试题集合
2013/05/21 面试题
市场营销专科应届生求职信
2013/11/24 职场文书
2015年元旦文艺汇演主持词
2014/03/26 职场文书
课外活动总结范文
2014/07/09 职场文书
实习工作表现评语
2014/12/31 职场文书
劳动仲裁调解书
2015/05/20 职场文书
CSS巧用渐变实现高级感背景光动画
2021/12/06 HTML / CSS
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL
详解JavaScript的计时器和按钮效果设置
2022/02/18 Javascript
OpenFeign实现远程调用
2022/08/14 Java/Android