命名空间其实早在PHP5.3就已经出现了。不过大部分同学可能在各种框架的使用中才会接触到命名空间的内容,当然,现代化的开发也都离不开这些能够快速产出的框架。这次我们不从框架的角度,仅从简单的代码角度来解析一下命名空间的概念和使用。

首先,我们要定义命名空间是个什么东西。

其实就像操作系统的目录一样,命名空间就是为了解决类似于操作系统中同一个文件夹不能有相同的文件名一样的问题。假设我们只有一个文件,一个目录,那么在这个目录中,是不能有两个完全相同的文件的。如果有这样名称完全相同的文件,那么操作系统也不知道我们到底应该打开的是哪一个文件。同理,在一个PHP文件中,我们也不能起相同名称的函数或者类名,PHP也不知道我们到底要调用的是哪一个函数或者类。

理解了上述内容之后,再来看命名空间的语法,其实非常像我们的目录的定义。


namespace A\B\C;

这个命名空间的定义就是指出了当前命名空间是A\B\C。就像是C:\A\B\C这样一个文件夹一样。光说不练假把式,直接上代码来看看:

// file1.php
namespace FILE1; const CONST_A = 2;
function testA(){
echo 'FILE1\testA()', PHP_EOL;
} class objectA{
function test(){
echo 'FILE1\ObjectA', PHP_EOL;
}
}
// file2.php
namespace FILE2; const CONST_A = 3;
function testA(){
echo 'FILE2\testA()', PHP_EOL;
} class objectA{
function test(){
echo 'FILE2\ObjectA', PHP_EOL;
}
}

我们在namespace目录下创建了这两个php文件,函数和类名都是一样的,但定义了不同的命名空间,一个是FILE1,一个是FILE2。

namespace A;

include 'namespace/file1.php';
include 'namespace/file2.php'; use FILE1, FILE2;
use FILE1\objectA as objectB; const CONST_A = 1;
function testA(){
echo 'A\testA()', PHP_EOL;
} class objectA{
function test(){
echo 'A\ObjectA', PHP_EOL;
}
} // 当前命名空间
echo CONST_A, PHP_EOL; // 1
testA(); // A\testA()
$oA = new objectA();
$oA->test(); // A\ObjectA // FILE1
echo FILE1\CONST_A, PHP_EOL; // 2
FILE1\testA(); // FILE1\testA()
$oA = new FILE1\objectA();
$oA->test(); // FILE1\ObjectA $oB = new objectB();
$oB->test(); // FILE1\ObjectA // FILE2
echo FILE2\CONST_A, PHP_EOL; // 3
FILE2\testA(); // FILE2\testA()
$oA = new FILE2\objectA();
$oA->test(); // FILE2\ObjectA

在测试代码中,我们又定义了当前的命名空间为A。并include了file1.php和file2.php。并在这个文件中同时也定义了与file1.php和file2.php中相同的函数和类名。接下来我们依次调用这些静态变量、函数和类。

  • 在默认情况下,静态变量、函数、类调用的是当前命名空间下的内容
  • 在使用了FILE1\和FILE2\之后,调用的是就是指定命名空间下的内容
  • 需要使用use引入命名空间,否则无法使用命名空间里的内容
  • use中可以使用as关键字为命名空间或者其中的类指定别名

命名空间的使用其实就是这么的简单。可以看出我们在不同的命名空间中就可以使用相同的函数或者类名了。这一点正是各类现代化开发框架的基础。同时也是composer能够实现的最主要的原因之一。

接下来,我们尝试一个问题是否符合我们的预期,那就是两个文件定义相同的命名空间是否能够定义相同的类名呢?

// file1-1.php
namespace FILE1; const CONST_A = 1.1;
function testA(){
echo 'FILE1-1\testA()', PHP_EOL;
} class objectA{
function test(){
echo 'FILE1-1\ObjectA', PHP_EOL;
}
}

我们定义了一个file1-1.php,并且使用了和file1.php相同的FILE1命名空间。然后和file1.php一起include到测试代码中。

include 'namespace/file1.php';
include 'namespace/file1-1.php'; // Cannot redeclare FILE1\testA()

好吧,在运行时直接就报错,不能重复定义同名的函数名。如果注释掉函数,那么会继续报类名不能重复。我们再定义一个file1-2.php,这次还是使用FILE1这个命名空间,但是内容不一样了。

// file1-2.php
namespace FILE1; const CONST_A = 1.2;
function testA1_2(){
echo 'FILE1-2\testA()', PHP_EOL;
} class objectA1_2{
function test(){
echo 'FILE1-2\ObjectA', PHP_EOL;
}
}

这样当然就没问题啦。这两个文件在同一个命名空间下,但是却有着不同的能力,这样是完全OK的操作。

include 'namespace/file1.php';
include 'namespace/file1-2.php';
use FILE1; // FILE1
echo FILE1\CONST_A, PHP_EOL; // 2
FILE1\testA(); // FILE1\testA()
$oA = new FILE1\objectA();
$oA->test(); // FILE1\ObjectA // FILE1_2
echo FILE1\CONST_A, PHP_EOL; // 3
FILE1\testA1_2(); // FILE1-2\testA()
$oA = new FILE1\objectA1_2();
$oA->test(); // FILE1-2\ObjectA

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202001/source/PHP%E4%B8%AD%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E6%98%AF%E6%80%8E%E6%A0%B7%E7%9A%84%E5%AD%98%E5%9C%A8%EF%BC%9F%EF%BC%88%E4%B8%80%EF%BC%89.php

参考文档:

https://www.php.net/manual/zh/language.namespaces.rationale.php

https://www.php.net/manual/zh/language.namespaces.definition.php

===============

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

PHP中命名空间是怎样的存在(一)?的更多相关文章

  1. php中命名空间和use

    php中命名空间和use 总结 php中的namespace就有点像java中package包的概念 php中的use的概念就是用别人的命名空间中的类 php中的include enquire是引入文 ...

  2. C#中命名空间,C#程序中的一种代码组织形式,主要用来标识类的可以范围,引用using 命名空间

    C# C#中命名空间,C#程序中的一种代码组织形式,主要用来标识类的可以范围 use system; use system.collect.core; namespace sss{ } using 命 ...

  3. TypeScript 中命名空间与模块的理解?区别?

    一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...

  4. php中命名空间的使用

    简单使用 命名空间主要解决函数/类冲突的问题.由于PHP中中不允许函数重载,所以我们要使用的到命名空间的.先看一个简单的例子. <?php namespace A; public functio ...

  5. spring-mvc.xml与spring-mybatis.xml配置文件中命名空间问题

    首先贴出配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="htt ...

  6. Python中命名空间与作用域使用总结

    1 引言 命名空间与作用域是程序设计中的基础概念,深入理解有助于理解变量的生命周期,减少代码中的莫名其妙bug.Python的命名空间与作用域与Java.C++等语言有很大差异,若不注意,就可能出现莫 ...

  7. C#中命名空间别名的使用

    C#中使用命名空间来分割不同的层级,在不同的层级中可以使用相同的类声明和变量声明.在程序中使用不同命名空间的下的相同名称的类时:可以用一下这几种方法进行限定: 1.使用完全限定名 using Syst ...

  8. 详解C++中命名空间的意义和用法

    看过鸡啄米的C++编程入门系列教程的朋友,应该能注意到,在其中的很多实例中,都有这么一条语句:using namespace std;,即使用命名空间std,其作用就是规定该文件中使用的标准库函数都是 ...

  9. 关于c++中命名空间namespace

    一.定义命名空间: 步骤一:在.h文件中:namespace  ns{.......}//将定义的类和全局变量,全局函数写入花括号内. 步骤二:在.cpp文件中: using namespace ns ...

  10. php中命名空间namespace和use

    对于面向对象编程而言,命名空间namespace和use的概念非常重要. 1.根命名空间是反斜线 \ ,有点类似linux中的根目录 / 的那种感觉,但使用var_dump()函数打印时其实是空字符串 ...

随机推荐

  1. 不懂Ribbon原理的可以进来看看哦,分析SpringBoot自动装配完成了Ribbon哪些核心操作

      前面详细的给大家介绍了SpringBoot的核心内容,有了这部分的基础支持的话,我们再来分析SpringCloud中的相关组件就很容器了,本文我们来给大家开始介绍Ribbon的相关内容,首先来介绍 ...

  2. linux服务器下TCP抓包

    1.首先ifconfig查看当前服务器的网卡信息 2.执行tcpdump -i ens160[网卡信息] -s 0 port 8080[监听的端口号] -w ./fileName.pcapng 3.可 ...

  3. epoll水平/边缘触发模式下阻塞/非阻塞EPOLLOUT事件触发条件及次数

    在IO多路复用技术中,epoll默认的事件触发模式为Level_triggered(水平触发)模式,即当被监控的文件描述符上有可读/写事件发生时,epoll_wait()会通知处理程序去读写.如果这次 ...

  4. Python小白的数学建模课-19.网络流优化问题

    流在生活中十分常见,例如交通系统中的人流.车流.物流,供水管网中的水流,金融系统中的现金流,网络中的信息流.网络流优化问题是基本的网络优化问题,应用非常广泛. 网络流优化问题最重要的指标是边的成本和容 ...

  5. HTML5内嵌文本编辑器

    1.这个编辑器用的是KindEditor 先看下效果: 2.准备: a):从官网下载KindEditor--->http://kindeditor.net/down.php b):解压到桌面测试 ...

  6. Spring中的@Transactional必须要了解的概念

    spring中的@Transactional基于动态代理的机制,提供了一种透明的事务管理机制,方便快捷解决在开发中碰到的问题. 一般使用是通过如下代码对方法或接口或类注释: 1 @Transactio ...

  7. vue--三种组件中之间的传值

    参考网址:https://www.jianshu.com/p/46573a741c29 一.父子组件之间的传值----props/$emit 组件之间的传值,我们比较常用到的是props/$emit ...

  8. [转]用C++实现插件体系结构

    本文讨论一种简单却有效的插件体系结构,它使用C++,动态链接库,基于面向对象编程的思想.首先来看一下使用插件机制能给我们带来哪些方面的好处,从而在适当时候合理的选择使用. 1. 增强代码的透明度与一致 ...

  9. 因为手机设置字体大小导致h5页面在webview中变形的BUG

    出现这个问题,有以下因素 你的页面采用了rem单位,并且是采用js动态计算html的font-size你的页面被加在了APP中的webview中这该死的手机被重设了字体大小解决方法一般,我们动态计算好 ...

  10. JavaWeb之数据库连接池

    时间:2016-12-2 23:56 --DBCP连接池连接池参数(所有连接池参数都有默认值):    初始大小    最小空闲连接数    增量    最大空闲连接数    最大连接数    最长等 ...