PHP中命名空间是怎样的存在(一)?
命名空间其实早在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://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中命名空间是怎样的存在(一)?的更多相关文章
- php中命名空间和use
php中命名空间和use 总结 php中的namespace就有点像java中package包的概念 php中的use的概念就是用别人的命名空间中的类 php中的include enquire是引入文 ...
- C#中命名空间,C#程序中的一种代码组织形式,主要用来标识类的可以范围,引用using 命名空间
C# C#中命名空间,C#程序中的一种代码组织形式,主要用来标识类的可以范围 use system; use system.collect.core; namespace sss{ } using 命 ...
- TypeScript 中命名空间与模块的理解?区别?
一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...
- php中命名空间的使用
简单使用 命名空间主要解决函数/类冲突的问题.由于PHP中中不允许函数重载,所以我们要使用的到命名空间的.先看一个简单的例子. <?php namespace A; public functio ...
- spring-mvc.xml与spring-mybatis.xml配置文件中命名空间问题
首先贴出配置文件: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="htt ...
- Python中命名空间与作用域使用总结
1 引言 命名空间与作用域是程序设计中的基础概念,深入理解有助于理解变量的生命周期,减少代码中的莫名其妙bug.Python的命名空间与作用域与Java.C++等语言有很大差异,若不注意,就可能出现莫 ...
- C#中命名空间别名的使用
C#中使用命名空间来分割不同的层级,在不同的层级中可以使用相同的类声明和变量声明.在程序中使用不同命名空间的下的相同名称的类时:可以用一下这几种方法进行限定: 1.使用完全限定名 using Syst ...
- 详解C++中命名空间的意义和用法
看过鸡啄米的C++编程入门系列教程的朋友,应该能注意到,在其中的很多实例中,都有这么一条语句:using namespace std;,即使用命名空间std,其作用就是规定该文件中使用的标准库函数都是 ...
- 关于c++中命名空间namespace
一.定义命名空间: 步骤一:在.h文件中:namespace ns{.......}//将定义的类和全局变量,全局函数写入花括号内. 步骤二:在.cpp文件中: using namespace ns ...
- php中命名空间namespace和use
对于面向对象编程而言,命名空间namespace和use的概念非常重要. 1.根命名空间是反斜线 \ ,有点类似linux中的根目录 / 的那种感觉,但使用var_dump()函数打印时其实是空字符串 ...
随机推荐
- WPF listbox 实现动态滚轮下拉定位
private ObservableCollection<keymodel> _listlua; public ObservableCollection<keymodel> l ...
- NOIP 模拟 $38\; \rm c$
题解 \(by\;zj\varphi\) 发现就是一棵树,但每条边都有多种不同的颜色,其实只需要保留随便三种颜色即可. 直接点分治,将询问离线,分成一端为重心,和两端都不为重心的情况. 每次只关心经过 ...
- NOIP 模拟 9 考试总结
T1 一道推规律的题,没想出来,暴力打得常数还太大了,挂了不少 题解 T2 这是一道二分题,很巧妙,但是对于想我一样懒得人,那个数据结构就水过去了 (裸的分块加强大的卡长和合适的块的大小可以卡过去) ...
- Swagger2常用注解解析(轻松构建Swagger)
Swagger2常用注解解析 一.SpringBoot集成Swagger2 二.常用注解解析 具体使用举例说明: 一.SpringBoot集成Swagger2 引入相关jar包 <!-- swa ...
- rabbitMq镜像集群
rabbitMq延迟投递的方案 1 把消息记录到数据路,通过定时器进行刷新 2 TTL 加上死信队列 :通过路由把过期的消息同步到死信队列,通过死信队列的消费者进行消费 3
- redis集群访问,重启,关闭,带密码访问集群
安装ruby后查找如下文件 vi 进去后编辑 此处编写自己的密码,重启后便可带密码访问集群 随便选择一个节点输入如下指令查看集群信息 正常关闭redis命令如下: 重启redis集群再次以相同的命 ...
- redis《三》连接池配置参数
参数 值 setTestWhileIdle() 在空闲时检查有效性 true setMinEvictableIdleTimeMillis() 连接最小空闲时间 1800000L setTimeBetw ...
- Ajax的GET,POST方法传输数据和接收返回数据
//首先创建一个Ajax对象 function ajaxFunction(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safari xmlHttp=new ...
- Ubuntu 16.04 + Win10双系统 启动Ubuntu进入命令行 无界面
Ubuntu 16.04 + Win10双系统,启动Ubuntu时候报错,并入命令行(无界面). 原因:可能是双系统兼容性问题 解决办法: 重启系统,进入Win10 然后在Win10中重启电脑. 重启 ...
- Python面试题小试牛刀
1.声明变量注意事项有那些? 1.变量名只能用字母.数字或下划线的任意组合 2.变量名不能以数字为第一个字符 3.内置函数名不能用 2.如何查看变量在内存中的地址? id(变量名) 3.写代码 a. ...