目录php
命名空间是相似于文件系统的一个虚拟容器,能够用于类(包括抽象类和traits)、接口、函数、常量。bash
相似于文件系统,能够把类放进一个多层级的命名空间,主要是解决类名的命名冲突问题。app
<?php
namespace haha\hehe\heihei
const CON1 = 10;
function run(){
//....
}
class ClassA{
//....
}
- 用namespace声明一个命名空间,代表接下去的代码属于这个命名空间
- 声明语句必须是文件第一句
- 也能够在后面加个大括号来显式代表这个命名空间范围,这样能够作到一个文件中有多个命名空间,可是很是不建议这样,不必,没有可读性,通常就是这样使用,也不用大括号
复制代码
没有命名空间以前,就是ide
require('\src\ClassA.php');
new ClassA();
复制代码
有了命名空间后函数
//如今都配合自动加载,不require
new \haha\hehe\heihei\ClassA();
复制代码
若是屡次要new一个对象,以为累赘,能够这样ui
use haha\hehe\heihei\ClassA; //注意最前面的斜杠能够省略
$obj1 = new ClassA();
$obj2 = new ClassA();
$obj3 = new ClassA();
复制代码
这叫导入类,还能够给类起别名spa
use haha\hehe\heihei\ClassA as A; //注意最前面的斜杠能够省略
new A();
复制代码
<?php
namespace My\n1amespace
new \app\controller\User(); //彻底限定名 很清楚
new User(); //就解析为My\n1amespace\User
new haha\User(); //就解析为My\n1amespace\haha\User
复制代码
__NAMESPACE__常量code
<?php
namespace My\n1amespace{
echo 'inside'.__NAMESPACE__; //My\n1amespace 若是没有命名空间就是''
}
复制代码
若是你须要用一个类,那你得先require,当你用一个类的时候,可能无所谓,当你的类用的多的时候,就很麻烦了。对象
自动加载1.0,在命名空间出现以前,就有自动加载,与原理就是,你能够告诉php解释器一个函数(用__autoload()或者spl_autoload_register()注册
),当你用一个类,而又没有导入的时候,系统就会运行这个函数。接口
自动加载2.0,在命名空间出现后,PSR-4规定了一个基于命名空间的统一的自动加载规范
其实问题的核心是,如何从命名空间,获得实际的文件位置?
两点
看一个例子就知道
spl_autoload_register(function($class_name){
//命名空间前缀
$prefixe = '\Foo\\Bar';
//基目录
$base_dir = __DIR__.'/src/';
//匹配是否 是在寻找这个命名空间下的类
$len = strlen($prefix);
if(strncmp($prefix,$class_name,$len)!==0){
return ;
}
//将命名空间转换为目录位置
$relative_class = substr($class.$len);
$file = $base_dir . str_replace('\\','/',$relative_class).'.php';
if(file)existst($file)){
require($file);
}
})
复制代码
参考资料