在PHP中,函数、类和常量都是不允许同名的,一旦同名就会出现错误。但是在大型项目开发中,不同团队负责的模块可能不同,那么就很难避免出现同名结构,所以“命名空间”就产生了,“命名空间”保证了即使出现了同名结构,也不会影响到整个项目。
非限定名称访问:成员前面不能有任何的命名空间,不能有“\”,理解成文件当前路径,如:echo Human::PERSON_NAME。
限定名称访问:成员名称前面至少要有一个命名空间,至少要有一个反斜线“\”,且不能在首位,理解成相对路径。限定名称的访问是基于子空间来实现的,如 echo space2\Human::PERSON_NAME。
完全限定名称访问:这个访问方式是默认的,用的最多的。访问总是从根空间(即全局空间)开始访问,第一个字符一定是反斜线(“\”),可以将完全限定名称访问理解成绝对路径,使用“\”作为全局空间开始符号。 如 echo \space3\Human::PERSON_NAME。
代码举例:
namespace space1;
echo __NAMESPACE__ . '<br>';
class Human
{
const PERSON_NAME = '王小丁';
}
//1.非限定名称
echo Human::PERSON_NAME;
echo '<hr>';
//2.限定名称
namespace space;
echo space2\Human::PERSON_NAME . '<br>';
namespace space\space2;
echo __NAMESPACE__ . '<br>';
class Human
{
const PERSON_NAME = '王小丁';
}
//3.完全限定名称(默认的,用的最多的)
echo '<hr>';
namespace space3;
echo __NAMESPACE__ . '<br>';
class Human
{
const PERSON_NAME = '王小丁';
}
echo \space3\Human::PERSON_NAME;
输出效果:
PHP 命名空间支持有两种使用别名或导入方式:为类名称使用别名,或为命名空间名称使用别名。
代码举例:
//1.命名空间的别名
namespace myspace1;
class C1
{
//...
}
echo \myspace2\C2::index(),'<br>';
echo \myspace2\C3::cate(),'<hr>';
namespace myspace2;
class C2
{
public static function index()
{
return '首页';
}
}
class C3
{
public static function cate()
{
return '频道页';
}
}
namespace myspace3;
//use 用来声明空间别名,use默认就是从根空间开始
//给外部的空间起了一个别名,myspace2 ===> s
use myspace2 as s;
echo s\C2::index(),'<br>';
echo s\C3::cate(),'<hr>';
//2.类级的别名
//给外部空间中的类,起一个别名
// use myspace2\C2 as C2;
// use myspace2\C3 as C3;
// echo C2::index(),'<br>';
// echo C3::cate(),'<hr>';
//类别名与原始类名相同,此时可以省略类别名,虽然可以这样使用,但是建议起上名字
// use myspace2\C2;
//因为当前类中与有一个与之冲突的类名C2
use myspace2\C2 as C;
use myspace2\C3;
echo C2::index(),'<br>';
echo C::index(),'<br>';
echo C3::cate(),'<hr>';
class C2
{
public static function index()
{
return '首页NS-T2';
}
}
输出效果:
如果想实现自动加载,需要满足两个条件
1.命名空间必须和类文件所在的绝对路径一一对应
2.当前类名称与当前的类文件的名称完全一致
//封装自动加载器
//需要在同一路径下创建一个或者几个php文件,且需要创建一个autoload.php文件来作引入桥梁
require 'autoload.php';
echo '<hr>';
use inc\lib\Demo1;
use inc\lib\Demo2;
use inc\lib\Demo3;
echo Demo1::say(),'<br>';
echo '<hr>';
echo Demo2::say(),'<br>';
echo '<hr>';
echo Demo3::say(),'<br>';
echo '<hr>';
autoload.php代码举例
try{
spl_autoload_register(function($className){
//1.应该将类名中的命名空间的分隔符转为目录分隔符
$path = str_replace('\\',DIRECTORY_SEPARATOR,$className);
echo $path, '<br>';
//2.生成真正要加载的类文件名称
$file = __DIR__ . DIRECTORY_SEPARATOR .$path .'.php';
echo $file,'<br>';
//3.加载这个文件
require $file;
});
}catch (Exception $e) {
die($e->getMessage());
}
输出效果:
1.不同的命名空间里面可以定义同名的函数、类和常量。
2.命名空间里可以书写任意代码。
3.非限定名称访问,直接访问当前目录。
4.限定名称访问,访问的是当前目录的子目录。
5.完全限定名称访问,是从全局即根目录下开始访问。
6.全局空间的元素访问使用完全限定名称访问
7.系统内置的类、函数和常量都属于全局空间。
8.系统函数、常量,在命名空间内访问的时候,系统会自动在自己空间找,如果找不到会到全局空间找。
9.系统类必须使用全局空间访问:\类名
10.命名空间的别名可以简化代码。
11.类文件的自动加载虽然在嵌套时需要创建多个文件,但是对于后期的数据维护与更新,却是简洁方便的。