各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案各类知识收集,PHP技术分享与解决方案

Str Tom,为分享PHP技术和解决方案,贡献一份自己的力量!
收藏本站(不迷路),每天更新好文章!
当前位置:首页 > CMS教程 > PHP

php源码之实现MVC结构微型框架

管理员 2023-09-05
PHP
153

php源码之实现MVC结构微型框架

内容导读

收集整理的这篇技术教程文章主要介绍了php源码之实现MVC结构微型框架,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含11190字,纯文字阅读大概需要16分钟

内容图文

这篇文章主要介绍了关于php源码之实现MVC结构微型框架,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

主要:

  1. 常量优化路径

  2. 自动加载类

  3. 优化入口文件

  4. 安全访问项目目录


----------------------------------------------------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中文网!

相关推荐:

php源码之区分平台MVC结构的介绍

php源码之实现单入口MVC结构的方法

以上就是php源码之实现MVC结构微型框架的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的php源码之实现MVC结构微型框架全部内容,希望文章能够帮你解决php源码之实现MVC结构微型框架所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

扫码关注

qrcode

QQ交谈

回顶部