主要:
常量优化路径
自动加载类
优化入口文件
安全访问项目目录
----------------------------------------------------blog├─app│ ├─model 模型│ │ └─usermodel.class.php 用户模型类 │ ├─view 视图│ │ ├─back后台│ │ │ └─index│ │ │ └─index.html 后台首页面│ │ └─home前台│ │ └─user 用户视图目录│ │ └─login.html 登录表单页面│ ├─controller 控制器│ │ ├─back后台│ │ │ └─indexcontroller.class.php 后台首页控制器│ │ └─home前台│ │ └─usercontroller.class.php 用户控制器├─public 静态公共文件(js,css,images)│ ├─plugins 插件│ │ └─layui 前端框架插件│ ├─back后台│ │ ├─js/ js文件│ │ ├─css/ css样式文件│ │ └─image img图片 │ └─home前台│ ├─js/ js文件│ ├─css/ css样式文件│ └─image img图片 ├─frame 公共使用的类│ ├─basemodel.class.php 数据库连接类│ ├─basecontroller.class.php 控制器公共操作(设置编码,信息跳转)│ ├─factorymodel.class.php 模型工厂类│ ├─init.class.php 初始化应用类│ └─mysqldb.class.php 数据库操作工具类└─index.php 入口文件-----------------------------------------------------------------
上一篇中,提出4个问题待解决,本篇集中解决这4个问题,最终形成完整的微型mvc框架结构, 后续博客项目,或其他项目,均可以直接使用该框架结构进行开发学习。
下载查看该项目源码: https://gitee.com/newbiesyang/young_blog
常量优化路径准备: 创建分支
1 $ git checkout master2 $ git checkout -b "mvc"
思路1)把常用的目录路径定义成常量。如 模型目录,控制器目录等
2)引入类使用定义的常量替代部分路径。 如 include frame.basemodel.class.php
3) 载入视图使用常量替代部分路径 如 include view.'login.html' 简单形式
代码实现 1)操作步骤
step 1: 在入口文件中定义所需要的常量step 2: 控制器中引入视图时, 使用常量进行优化
操作步骤思路
2) 入口文件中定义常用路径常量 【index.php】
1 <?php 2 /** 3 * 入口文件 4 */ 5 $p = !empty($_get['p']) ? $_get['p'] : 'home'; //平台 6 $c = !empty($_get['c']) ? $_get['c'] : 'user'; //控制器 7 $a = !empty($_get['a']) ? $_get['a'] : 'login'; //动作 8 9 define('plat', $p); //平台常量 10 define('ctr', $c); //控制器 11 define('action', $a); //动作 12 13 14 define('ds', directory_separator); //目录分割符 15 define('root', getcwd().ds); //当前所在目录 项目目录 16 define('frame', root.'frame'.ds); 17 define('app', root.'app'.ds); 18 define('pub', root.'public'.ds); 19 define('admin', pub.'admin'.ds); 20 define('home', pub.'home'.ds); 21 22 //mvc目录 23 define('model', app.'model'.ds); 24 define('view', app.'view'.ds.plat.ds.ctr.ds); 25 define('ctronller', app.'controller'.ds.plat.ds); 26 27 $ctr = $c."controller"; 28 29 require_once frame.'db.class.php'; //数据库操作类 30 require_once frame.'basemodel.class.php'; //基础模型类 31 require_once model.'usermodel.class.php'; //用户模型类 32 require_once frame.'factorymodel.class.php';//模型工厂类 33 require_once frame.'basecontroller.class.php'; //基础控制器类 34 require_once ctronller.$ctr.'.class.php'; 35 36 37 //实例化控制器 38 $userctr = new $ctr(); 39 40 $userctr -> $a();
2) 常量的使用:
后台首页控制器【app/controller/admin/indexcontroller.class.php】
1 <?php 2 /** 3 * indexcontroller控制器类 4 * 后台相关操作 5 * user: young 6 */ 7 8 class indexcontroller extends basecontroller 9 { 10 //展示后台首页 11 public function index() 12 { 13 include view.'index.html'; 14 } 15 }
后台首页控制器引入视图路径修改
用户控制器 登录视图引入路径【app/controller/home/usercontroller.class.php】
1 <?php 2 /** 3 * usercontroller.class.php 用户控制器 4 */ 5 6 class usercontroller extends basecontroller{ 7 /** 8 * 展示登录界面 9 * @access public 10 */ 11 public function login() 12 { 13 include view."login.html"; 14 } 15 。。。 16 。。。 17 。。。
用户控制器登录视图引入路径
3)提交代码
$ git add -a$ git commit -m "常量使用"
自动加载类 思路问题: 入口文件中已经require_once 引入6个类,既增加一个需要引入一个,容易遗漏,重复和出错。
解决方法:自动加载类文件
方式1: 使用自动加载类函数__autoload()可以实现自动加载
方式2: 实际项目中,多人开发,根据实用性,更多的是使用 sql_autoload_register()注册函数自动加载
根据目录的特点实现自动加载
model类文件特点,以model结尾的类名 substr($classname,-5)
controller文件特点: 以controller结尾的类名, substr($class,-10)
公共类: 类名没有统一形式,可以将fame下的公共类放入到数组中,然后判断类是否在数组中, 从而自动加载该目录下的类文件
代码实现 1) 入口文件实现类的自动加载
1 <?php 2 /** 3 * 入口文件 4 */ 5 $p = !empty($_get['p']) ? $_get['p'] : 'home'; //平台 6 $c = !empty($_get['c']) ? $_get['c'] : 'user'; //控制器 7 $a = !empty($_get['a']) ? $_get['a'] : 'login'; //动作 8 9 define('plat', $p); //平台常量 10 define('ctr', $c); //控制器 11 define('action', $a); //动作 12 13 14 define('ds', directory_separator); //目录分割符 15 define('root', getcwd().ds); //当前所在目录 项目目录 16 define('frame', root.'frame'.ds); 17 define('app', root.'app'.ds); 18 define('pub', root.'public'.ds); 19 define('admin', pub.'admin'.ds); 20 define('home', pub.'home'.ds); 21 22 //mvc目录 23 define('model', app.'model'.ds); 24 define('view', app.'view'.ds.plat.ds.ctr.ds); 25 define('ctronller', app.'controller'.ds.plat.ds); 26 27 $ctr = $c."controller"; 28 29 spl_autoload_register('autoload'); //注册自动加载函数 30 //自动加载类 31 /** 32 * 实自动加载类文件 33 * @param string $classname 类名 34 */ 35 function autoload($classname) 36 { 37 $upperclassname = strtoupper($classname); 38 $frame = array('basecontroller','basemodel','db','factorymodel'); 39 if(in_array($classname, $frame)) { //加载公共frame目录中的类文件 40 require_once frame."$classname.class.php"; 41 } elseif(substr($upperclassname, -5) == 'model'){ //加载模型model目录中的类文件 42 require_once model."$classname.class.php"; 43 } elseif(substr($upperclassname, -10) == 'controller'){ //加载控制器目录中的类文件 44 require_once ctronller."$classname.class.php"; 45 } 46 } 47 48 //实例化控制器 49 $userctr = new $ctr(); 50 $userctr -> $a();
2) 提交代码
1 $ git add -a2 $ git commit -m "自动加载类完成"
优化入口文件思路问题: 此时,入口文件代码零碎增多,随着后续代码的增加,入口文件会更加臃肿复杂,不易管理
解决方法: 封装入口文件中的操作称为一个类,这样只需要在入口文件调用类的方法即可
创建init.class.php类文件,放入到frame中
将入口文件所有操作封装成类方法
loadclass() 设置自动加载函数
autoload()自动加载类
setconst() 定义常量
dispatch() 前端分发器
代码实现 1) 在frame目录中创建init.class.php文件, 将入口文件index中的代码复制进行修改为类
【frame/init.class.php】
1 <?php 2 /** 3 * 应用初始化操作类 4 * user: young 5 */ 6 7 class init 8 { 9 protected static $frame = array('basecontroller','basemodel','db','factorymodel'); //frame目录公共操作类 10 public static function run() 11 { 12 //平台 13 self::dispatch(); 14 15 //定义常量 16 self::setconst(); 17 18 //自动加载类 19 self::loadclass(); 20 21 $ctr = ctr."controller"; //拼接控制器名称 22 23 //实例化控制器 24 $ctrobj = new $ctr(); 25 $a = action; 26 $ctrobj -> $a(); 27 } 28 /** 29 * 设置自动加载类方法 30 */ 31 private static function loadclass() 32 { 33 spl_autoload_register('self::autoload'); 34 } 35 36 /** 37 * 实现自动加载 38 * @param string $classname 类名 39 */ 40 private static function autoload($classname) 41 { 42 $upperclassname = strtoupper($classname); 43 if(in_array($classname, static::$frame)) { 44 require_once frame."$classname.class.php"; 45 } elseif(substr($upperclassname, -5) == 'model'){ 46 require_once model."$classname.class.php"; 47 } elseif(substr($upperclassname, -10) == 'controller'){ 48 require_once ctronller."$classname.class.php"; 49 } 50 } 51 52 /** 53 * 定义常量 54 */ 55 private static function setconst() 56 { 57 define('ds', directory_separator); //目录分割符 58 define('root', getcwd().ds); 59 define('frame', root.'frame'.ds); 60 define('app', root.'app'.ds); 61 define('pub', root.'public'.ds); 62 define('admin', pub.'admin'.ds); 63 define('home', pub.'home'.ds); 64 65 66 define('model', app.'model'.ds); 67 define('view', app.'view'.ds.plat.ds.ctr.ds); 68 define('ctronller', app.'controller'.ds.plat.ds); 69 } 70 71 /** 72 * 获取 p c a 的get值,并设置为常量 73 * @return void 74 */ 75 private static function dispatch() 76 { 77 $p = !empty($_get['p']) ? $_get['p'] : 'home'; //平台 78 $c = !empty($_get['c']) ? $_get['c'] : 'user'; //控制器 79 $a = !empty($_get['a']) ? $_get['a'] : 'login'; //动作 80 81 define('plat', $p); 82 define('ctr', $c); 83 define('action', $a); 84 } 85 }
2) 入口文件引入初始化类,并调用其方法 【index.php】
1 <?php2 /**3 * 入口文件4 */5 6 require_once './frame/init.class.php';7 init::run();
3) 提交代码
1 $ git add -a2 $ git commit -m "优化入口文件,封装初始化类"
安全访问项目目录 思路问题: 此时,项目中所有目录都是可以通过浏览器访问的,如直接访问frame/db.class.php文件 直接可以去查看数据库登录信息,显然是不安全的。
解决方法:
方式1: 在可以访问的文件开始处定义常量,访问是判断是否定义常量defined(..), 没有定义指定常量则直接exit('access deny');
方式2: 开启分布式权限配置,编写.htaccess文件, 如禁止访问, 将该文件放置在禁止访问的目录中
实现1)使用上述方式2的形式来实现, 站点配置中加入一项(环境搭建时已经加入了): 详细见: php源码搭建博客1-环境搭建
apache配置文件httpd-vhosts.conf 中站点配置
1 #允许分布式权限配置(允许重写)(.htacess)2 allowoverride all
2) 重启apache后,编写 .htaccess文件, 该文件内容:
deny from all
3) 将.htaccess文件放置禁止访问的目录中。 如app/ , frame/ 目录下。只用放在第一层即可,内层目录自动不允许直接访问。
4) 访问测试
小结:主要实现了 引入路径优化, 类的自动加载, 封装优化入口文件,目录访问限制
mvc微型框架到此基本完成。其实还有很多还是可以继续扩展,如
1, 类文件命名此处都用了 .class.php结尾, 实质可以优化直接使用.php结尾
2, 引入命名空间,更方便的加载类
3, 项目中出现错误,此时是直接显示在浏览器上的, 可以写一个日志类,发生错误写入文件或数据库都可
4, 数据库连接信息此处是直接写在db类和basemodel中了, 是不安全的。 可以创建一个配置目录,将这些信息写入配置文件,再写一个加载配置文件的类。
5. 此架构目录 ,是在c,v中分平台,如controller/home, controller/admin; 实际也可以写成 平台下分mvc结构, 如admin/controller, admin/model, home/controller,home/view .. 这个是比较灵活的,可以根据需求选择更加合适的方式
实际上线项目,还是建议使用框架,安全快捷; 自己模仿定义的框架结构适合学习研究使用,容易遗漏,造成安全隐患,操作不便等问题
下一步:根据博客前端模板,分析创建数据表, 开始搭建博客后台程序,后续首先准备实现 “分类模块”。既分类的展示,修改,添加,删除功能
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注!
相关推荐:
php源码之区分平台mvc结构的介绍
php源码之实现单入口mvc结构的方法
以上就是php源码之实现mvc结构微型框架的详细内容。
