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;});