이 글은 주로 PHP 소스 코드에서 MVC 구조 마이크로 프레임워크의 구현을 소개합니다. 이제 이를 모든 사람과 공유합니다. 도움이 필요한 친구들은 이를 참조할 수 있습니다.
주로:
지속적인 최적화 경로
자동으로 클래스 로드
항목 파일 최적화
프로젝트 디렉터리에 대한 보안 액세스
---------------------------------------------------- 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 master 2 $ git checkout -b "MVC"
1) 정의 일반적으로 사용되는 디렉터리 경로는 상수가 됩니다. 모델 디렉터리, 컨트롤러 디렉터리 등 2) 클래스를 도입하고 정의된 상수를 사용하여 경로의 일부를 대체합니다. include FRAME.BaseModel.class.php
3) include VIEW.'login.html' Simple form
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();
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 "常量使用"
방법 2: 실제 프로젝트에서는 여러 사람이 개발하며 실용성에 따라 sql_autoload_register()가 더 일반적으로 사용됩니다. 등록 기능이 자동으로 로딩됩니다
> · · · · · ,-10)
퍼블릭 클래스: 클래스 이름에 대한 통일된 형식이 없습니다. Fame 아래의 클래스를 배열에 추가한 다음 해당 클래스가 배열에 있는지 확인하여 디렉토리의 클래스 파일을 자동으로 로드
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 -A 2 $ git commit -m "自动加载类完成"
항목 파일 최적화
아이디어
코드 구현
1) 프레임 디렉토리에 Init.class.php 파일을 생성하고, 클래스에 대한 항목 파일 인덱스
【 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 }
1 <?php 2 /** 3 * 入口文件 4 */ 5 6 require_once './Frame/Init.class.php'; 7 Init::run();
3) 코드 제출
1 $ git add -A 2 $ 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 소스 코드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!