PHP:oop->细说命名空间/命名空间类的自动加载
一.命名空间
-
命名空间:namespace 有名称的空间
-
namespace 需要写在脚本的顶部,必须是php的第一条指令(除了declare指令)
-
全局成员: 常量,函数,类(接口),默认声明在全局空间中的
-
优点:全局调用
-
缺点:不能重复命名
-
php5.3以后引入C Java中应用成熟的命名空间
-
use 在命名空间中的作用/导入命名空间
-
use app\admin\controller as app;
-
引入别的命名空间到当前空间 为命名空间起别名
-
引入别的命名空间中的类到当前空间使用, 为别的命名空间中的类起别名
①命名空间->相互访问
在第二个命名空间中找不到第一个命名空间里面的类,如果我们要进行访问则要用\斜杆进行指定空间查找,可以理解为路径查找
在two空间中访问one空间里的类, 应该使用""表示root空间(全局空间)
代码块
<?php
/**
* namespace 需要写在脚本的顶部,必须是php的第一条指令(除了declare指令)
*
* namespace ns1;
* namespace ns1{
* }
*/
//第一个命名空间
namespace one
{
class index
{
public function Show()
{
return "这是one空间中的".__METHOD__."方法";
}
}
}
//第二个命名空间
namespace one2
{
echo (new \one\index)->Show();
}
②命名空间->优先级
如果存在同一个类和同一个方法但是命名空间不同,在哪个空间中调用的语句,优先级就是实例这个空间中的方法和类
如果想要访问别的空间,需要用\找到另外空间的成员
代码块
<?php
/**
* namespace 需要写在脚本的顶部,必须是php的第一条指令(除了declare指令)
*
* namespace ns1;
* namespace ns1{
* }
*/
//第一个命名空间
namespace one
{
class index
{
public function Show()
{
return "这是one空间中的".__METHOD__."方法";
}
}
//查看类的完全限定名称
echo index::class;
}
//第二个命名空间
namespace one2
{
class index
{
public function Show()
{
return "这是one2空间中的".__METHOD__."方法";
}
}
/*
*如果存在同一个类和同一个方法但是命名空间不同,
*在哪个空间中调用的语句,优先级就是实例这个空间中的方法和类
*/
echo ( new index)->Show();
echo "<br>";
echo index::class;
echo "<hr>";
/*
*如果想要访问别的空间,需要用\找到另外空间的成员
*/
echo (new \one\index)->Show();
echo "<br>";
}
③命名空间->自定义函数和系统函数优先级
- 假如在命名空间中,定义一个类方法,这个类方法和系统函数重名,那调用这个函数,会出现什么结果?
在命名空间中如果有一个函数和系统函数重名,我们去调用这个函数的话会优先调用自定义函数,而不是系统函数,因为系统函数是全局函数,要在根空间中查找
在子空间中加入\斜杆来查找根空间中的系统函数,如果子空间未定义这个系统函数,系统会默认调用根空间中的系统函数
代码块
<?php
/**
* namespace 需要写在脚本的顶部,必须是php的第一条指令(除了declare指令)
*
* namespace ns1;
* namespace ns1{
* }
*/
namespace one
{
class User{
/*
*假如在命名空间中,定义一个类方法
*这个类方法和系统函数重名,那调用这个函数
*会出现什么结果?
*/
//列如定义一个var_dump 和md5
public function var_dump()
{
return "你调用的是我".__METHOD__;
}
public function md5()
{
return "你调用的是我".__METHOD__;
}
}
//调用类中var_dump
echo (new User)->var_dump();
echo "<hr>";
//调用类中md5
echo (new User)->md5();
echo "<hr>";
//调用根空间函数
echo \md5("222");
}
④命名空间->Use在命名空间中的作用
- Use在命名空间中的作用
- 引入别的命名空间到当前空间 为命名空间起别名
- 引入别的命名空间中的类到当前空间使用, 为别的命名空间中的类起别名
- use 导入命名空间
成功导入命名空间以后 就可以不使用类的完全限定名称调用类元素
- use 为导入的空间取别名
as关键字可以给导入的空间取别名,防止导入的空间名称一样
- use 也可以导入空间中的类
use也可以直接导入空间中想要的类名称
代码块
<?php
/*
* use 在命名空间中的作用
* 1. 引入别的命名空间到当前空间 为命名空间起别名
* 2. 引入别的命名空间中的类到当前空间使用, 为别的命名空间中的类起别名
*/
//定义一个命名空间
namespace app\admin\index
{
//输出一个工作类
class demo4
{
public function Show()
{
return "输出当前的空间方法:".__METHOD__;
}
}
}
//用use 把另外一个命名空间引入到这个命名空间
namespace app\admin\connect
{
//1. use 导入命名空间
use app\admin\index;
// 成功导入命名空间以后 就可以不使用类的完全限定名称调用类元素
echo (new index\demo4)->Show(),'<hr>';
//2. use 为导入的空间取别名
use app\admin\index as one ;
echo (new one\demo4)->Show(),'<hr>';
//3. use 也可以导入空间中的类
use app\admin\index\demo4 ;
echo (new demo4)->Show(),'<hr>';
}
二.命名空间类的自动加载
代码块
<?php
/*
*类的自动加载
*spl_autoload_register — 注册给定的函数作为 __autoload 的实现
*/
spl_autoload_register(function($className)
{
//先检查当前要加载的类
printf("类名称:%s<br>",$className);
//-----------------------------
/*
*str_replace — 子字符串替换
*用DIRECTORY_SEPARATOR,自动识别当前系统文件分隔符
*解决在不同环境中的文件引用不同
*/
$file = str_replace('\\',DIRECTORY_SEPARATOR,$className).".php";
echo $file;
/*
* 判断此文件是否正常和是否为空,如果正常就返回
* is_file — 判断给定文件名是否为一个正常的文件
* file_exists — 检查文件或目录是否存在
*/
if( !(is_file($file) && file_exists($file)) )
throw new \Exception('文件名不合法或者文件不存在');
require $file;
});