PHP namespace:命名空间
什么是命名空间?从广义上来说,命名空间是一种封装事物的方法,在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。
举个简单的例子,文件foo.txt
可以同时在目录 /home/greg
和/home/other
中存在,但在同一个目录中不能存在两个 foo.txt
文件。另外,在目录 /home/greg
外访问foo.txt
文件时,我们必须将目录名以及目录分隔符放在文件名之前,例如 /home/greg/foo.txt
。这个原理应用到程序设计领域就是命名空间的概念。
PHP 命名空间可以解决以下两类问题:
- 用户编写的代码与 PHP 内部的类/函数/常量或第三方类/函数/常量之间的命名冲突;
- 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,以提高源代码的可读性。
- PSR-4规范 https://www.cnblogs.com/q1104460935/p/8084396.html
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oEdcG5Uf-1620898473547)(https://www.hualigs.cn/image/609a065cd4373.jpg)]
定义命名空间
定义命名空间使用namespace关键字
namespace命名空间名称解析规则
1.非限定名称:名称中不包含命名空间分割符,如:myself
2.限定名称:名称中含有命名空间分割符,如:admin\myself
3.完全限定名称:名称中包含分割符,并以命名空间分割符开始,如:\admin\myself (即绝对路径的概念)
虽然任意合法的 PHP 代码都可以包含在命名空间中,但只有类(包括抽象类和 traits)、接口、函数和常量等类型的代码受命名空间的影响。
<?php
/**
* 命名空间:namespace
* 全局成员: 常量,函数,类(接口),默认声明在全局空间中的
* 优点:全局调用
* 缺点:不能重复命名
*
*
* php5.3以后引入C# Java中应用成熟的命名空间
*/
// 在声明命名空间之前除了用于定义源文件编码方式的 declare 语句外,所有非 PHP 代码(包括空白符)都不能出现在命名空间声明之前
namespace MyProject;
const CONNECT_OK = 1;
interface Itest
{
public function getSite();
}
class className implements Itest {
public function getSite()
{
return __METHOD__." 命名空间<br>";
}
}
namespace OtherProject;
const CONNECT_OK = 1;
interface Itest
{
public function getSite();
}
class className implements Itest {
public function getSite()
{
return __METHOD__." 命名空间<br>";
}
}
// 也可以使用大括号进行包裹
namespace AnotherProject;
const CONNECT_OK = 1;
class className {
/* ... */
}
//在AnotherProject空间中访问MyProject空间里的类, 应该使用"\"表示root空间(全局空间)
echo (new \MyProject\className)->getSite();//绝对路径 类的完全限定名称\MyProject\className
echo (new \OtherProject\className)->getSite();
/*
MyProject\className::getSite 命名空间
OtherProject\className::getSite 命名空间
*/
?>
注意:在实际的编程实践中,并不提倡在同一个文件中定义多个命名空间。定义多个命名空间主要用于将多个 PHP 脚本合并在同一个文件中。在定义多个命名空间时建议使用大括号形式的语法。
将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法,同时全局代码必须用一个不带名称的 namespace 语句加上大括号括起来
<?php
namespace MyProject{
// 命名空间中的代码
const CONNECT_OK = 1;
class className {
/* ... */
}
}
namespace AnotherProject{
const CONNECT_OK = 1;
class className {
/* ... */
}
}
namespace {
// 命名空间外的全局代码 全局空间 匿名空间 公共空间