概念
从广义上来说,命名空间是一种封装事物的方法。在很多地方都可以见到这种抽象概念。例如,在操作系统中目录用来将相关文件分组,对于目录中的文件来说,它就扮演了命名空间的角色。
作用
- 用来解决用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
- 为很长的标识符创建一个别名,提高源代码可读性。
注意: 虽然任意合法的PHP代码都可以包含在命名空间中,但只有以下类型的代码受命名空间的影响,它们是:类(包括抽象类和traits)、接口、函数和常量。
PHP5.3开始const关键字可以用在类的外部。const和define都是用来声明常量的(它们的区别不详述),但是在命名空间里,define的作用是全局的,而const则作用于当前空间。我在文中提到的常量是指使用const声明的常量。
定义方法
- 通过关键字namespace 来声明;
注意: 必须在其它所有代码之前声明命名空间,除了一个以外:declare关键字。 - 单个命名空间声明方式:
namespace MyProject;
- 子命名空间声明方式:
namespace MyProject\Sub\Level;
- 同一个命名空间可以定义在多个文件中,即允许将同一个命名空间的内容分割存放在不同的文件中。 (不理解)2019-05-22理解了
也可以在单个文件中定义多个命名空间,建议使用下面的大括号形式的语法。
但是在实际的编程实践中,非常不提倡在同一个文件中定义多个命名空间。
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace AnotherProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
?>
- 将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,例如:
<?php
namespace MyProject {
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}
namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>
注意: 除了开始的declare语句外,命名空间的括号外不得有任何PHP代码。
元素的三种引用方式
- 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。
注意: 如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。
但是,在一个命名空间中,类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称。例如:
namespace Test;
var_dump(new Exception());
//Fatal error: Uncaught Error: Class 'Test\Exception' not found
- 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 (注意: 此处为当前命名空间虚拟路径,而不是currentdirectory当前文件路径=>) currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
- 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。
使用composer自动加载文件
项目初始
$ composer init
修改composer.json配置文件
其中 autoload配置项是自动加载设置。
files 是自动加载文件列表,适合于加载函数
psr-4 自动加载命名空间与目录对应关系
{
"name": "hd/php",
"authors": [
{
"name": "houdunren.com",
"email": "2300071698@qq.com"
}
],
"autoload": {
"files": [
"App/helper.php"
],
"psr-4": {
"App\\": "App"
}
},
"require": {}
}
安装与更新
修改配置文件后执行 composer install
生成vendor,如果修改过配置文件需要执行 composer update
。
配置
在项目中使用以下代码即可完成自动加载。
include 'vendor/autoload.php';