内容简介:当前入口文件 index.php 中的代码在加载控制器类时手动拼写路径,然后再执行 require_once 加载控制器文件再观察其他文件中,凡是涉及到加载文件时,全部都是手动加载
当前入口文件 index.php 中的代码
//入口文件:程序的入口 $c = isset($_GET['c']) ? $_GET['c'] : 'home'; $a = isset($_GET['a']) ? $_GET['a'] : 'getNewsList'; //获取模块名称 $m = isset($_GET['m']) ? $_GET['m'] : 'home'; //常量是可以跨页面访问的 define("MODULE", $m); $classname = $c . "Controller"; $actionname = $a . "Action"; //拼接的是控制器类所在的类文件的路径 $filename = "./application/" . $m . "/controller/" . $classname . ".class.php"; if (!file_exists($filename)) { echo "非法访问"; die(); } require_once $filename; $controller_name = new $classname(); $controller_name->$actionname();
在加载控制器类时手动拼写路径,然后再执行 require_once 加载控制器文件
再观察其他文件中,凡是涉及到加载文件时,全部都是手动加载
缺点:如果被包含文件的路径或者名称发生变化,修改起来麻烦
解决方案:删除所有文件中的 require_once ,不再手动包含文件,采用自动加载机制
1. 设置命名空间
设置命名空间之后,自动加载函数执行时获取的就是带有命名空间前缀的名称,这个名称也指明了类的路径,在我们稍后测试时可以看到
1.1 示例:
控制器基类 Controller 命名空间为
namespace framework\core;
此类的代码中又用到了 Smarty,所以也引入了 Smarty类的命名空间
use \Smarty;
所以最后代码如下
namespace framework\core; use \Smarty;
1.2 所有命名空间
下面以截图的方式列出所有类的命名空间及导入的命名空间
1.2.1 framework 目录下
1.2.2 admin 模块下的类
控制器类和模型类各选一个作为示例
1.2.3 home模块下的类
2. 重写入口文件
2.1 使用命名空间
这是对原来的入口函数做了简单的修改,将 require_once 删除
注意 $classname 变量的值,拼接时分隔符使用的是“\”,而不是“/”,区别在于,前者是命名空间分隔符,后者只是路径分隔符,所以此变量的值其实是请求的控制器类的带有命名空间前缀的名称
例如,我们请求如下地址
http://localhost/news/index.php
则模块名称、控制器名称和方法名称都将使用默认值,即 home-home-getNewsList,则变量 classname 的值为
home\controller\homeController
这正好是HomeController类的带有命名空间的名称,因为HomeController 类的命名空间就是
home\controller
2.2 编写自动加载函数
在入口文件中编写如下函数,并注册为自动加载函数
function my_autoload($className){ echo $className; } spl_autoload_register("my_autoload");
此时,入口文件的完整代码如下
//入口文件:程序的入口 //自动加载函数 function my_autoload($className){ echo $className; } //注册自动加载函数 spl_autoload_register("my_autoload"); $c = isset($_GET['c']) ? $_GET['c'] : 'home'; $a = isset($_GET['a']) ? $_GET['a'] : 'getNewsList'; //获取模块名称 $m = isset($_GET['m']) ? $_GET['m'] : 'home'; //常量是可以跨页面访问的 define("MODULE", $m); $classname = MODULE . "\\controller\\" . $c . "Controller"; $actionname = $a . "Action"; $c = new $classname(); $c->$actionname();
访问入口文件,输出如下
然后就可以写代码将其包含进来
function my_autoload($className){ echo $className."<br>"; require_once "./application/".$className.".class.php"; }
再次运行入口文件
错误在于,执行 HomeController 类时,其中还导入了其他命名空间的类
自动加载函数会自动加载此类所在的文件,所以会将参数 className 的值赋值给 framework/core/Controller
而在自动载入函数中又有如下代码
require_once "./application/".$className.".class.php";
所以会导致去错误的路径寻找文件
解决方法:加载文件时要分门别类,根据文件所在的目录判断
有些类的命名空间以 “framework” 开头,如上面 Controller类的命名空间"framework/core",有些类的命名空间则以模块名称开头,application 中的所有类都时这样
所以修改代码如下
function my_autoload($className){ //将类名按照“\”分割成数组 $ary=explode("\\",$className); if ($ary[0]=="framework"){ $baseDir="./"; }else{ $baseDir="./application/"; } $filename=$baseDir.$className.".class.php"; echo $filename."<br>"; require_once $filename; }
运行结果如下
在加载 smarty 类时出现错误,路径又不对了
所以Smarty 要特殊对待
function my_autoload($className){ //smarty类特殊对待 if ($className=="Smarty"){ require_once './framework/vender/smarty/Smarty.class.php'; return; } //将类名按照“\”分割成数组 $ary=explode("\\",$className); if ($ary[0]=="framework"){ $baseDir="./"; }else{ $baseDir="./application/"; } $filename=$baseDir.$className.".class.php"; echo $filename."<br>"; require_once $filename; }
再次运行
原因在于 Smarty_Autoloader.class.php 是Smarty 包中的文件,会自动加载,不需要在我们的自动载入函数中加载
再次运行
错误在于,i_DAO 是一个接口,名称不是 i_DAL.class.php ,而是 i_DAL.interface.php
所以再次修改代码
function my_autoload($className){ if ($className=="Smarty_Autoloader"){ return; } //smarty类特殊对待 if ($className=="Smarty"){ require_once './framework/vender/smarty/Smarty.class.php'; return; } //将类名按照“\”分割成数组 $ary=explode("\\",$className); if ($ary[0]=="framework"){ $baseDir="./"; }else{ $baseDir="./application/"; } //判断后缀名 if (strpos($className,"i_")){ $fix=".interface.php"; }else{ $fix=".class.php"; } $filename=$baseDir.$className.$fix; echo $filename."<br>"; require_once $filename; }
搞定!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Android 图片加载框架
- SpringCache框架加载/拦截原理
- Glide 图片加载框架源码解析
- 优雅地实现Android主流图片加载框架封装,可无侵入切换框架
- SDWebImage 4.3.1 发布,iOS 图片加载框架
- golang iris mvc框架的服务端加载过程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。