欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

php源码建博客3--区分平台的MVC结构

程序员文章站 2022-08-11 14:56:55
主要: 下载查看该项目源码: https://gitee.com/NewbiesYang/young_blog 模型单例工厂 准备: 创建分支 说明: 1)程序中3行 。。。 表示省略的代码。从前面或源码中可查看 2) 【XXX/XXX】表示项目文件相对路径 思路: 问题: 项目中模型操作数据表,一 ......

主要:

  1. 模型单例工厂
  2. 目录结构优化
  3. 区分平台(前台,后台....)

--------------文件结构:--------------------------------------
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  模型工厂类
│   └─MySQLDB.class.php 数据库操作工具类
└─index.php  入口文件 ----------------------------------------------------------------

 下载查看该项目源码:

模型单例工厂

准备: 创建分支

1 $ git checkout master
2 $ git checkout -b "folder-model-app"

说明:

  1)程序中3行 。。。 表示省略的代码。从前面或源码中可查看

  2) 【XXX/XXX】表示项目文件相对路径

  思路:

  问题: 项目中模型操作数据表,一个动作可能就要操作一次数据库,一次请求多个动作,每个动作都需要去实例化对应模型

  解决想法: 创建一个模型类单例工厂
       实现: 创建单例的模型类  FactoryModel.class.php
          属性$model=array(); 存储模型类实例
          方法: M($cmodelName, array $conf=null) 实例化模型类
      使用: 控制器中使用模型类实例:$model=FactoryModel::M('模型名称')

  代码实现

1) 创建模型单例工厂 【Frame/FactoryModel.class.php】

 1 <?php
 2 /**
 3  * 单例模型工厂类
 4  * User: young
 5  */
 6 
 7 class FactoryModel
 8 {
 9     protected static $model = array(); //存储模型类实例
10 
11     /**
12      * 构造方法
13      */
14     protected function  __construct()
15     {
16     }
17 
18     /*
19      * 传递一个模型类的类名,就返回该类的一个单例实例对象
20     *@param string $modelName  模型类的类名
21     *@param array  $conf  数据库配置信息
22     *@return object 传入模型类的实例(单例)
23     */
24     public static function M($modelName, array $conf=null)
25     {
26         $modelName = $modelName.'Model';
27         if(empty(static::$model[$modelName]) || !(static::$model[$modelName] instanceof $modelName)){
28             static::$model[$modelName] = new $modelName($conf);
29         }
30         return static::$model[$modelName];
31     }
32 }

2) 引入该类文件 【index.php】

php源码建博客3--区分平台的MVC结构
 1 <?php
 2 /**
 3  * 入口文件
 4  */
 5 require_once 'Frame/Db.class.php';  //数据库操作类
 6 require_once 'Frame/BaseModel.class.php';  //基础模型类
 7 require_once('Model/UserModel.class.php');
 8 
 9 require_once 'Frame/FactoryModel.class.php';//模型工厂类
10 。。。
11 。。。
12 。。。
入口文件引入工厂模型类

3) 应用: 控制器中使用,如用户控制器UserController中 登录操作【Controller/UserController.class.php】

 1  <?php
 2 /**
 3  * UserController.class.php 用户控制器
 4  */
 5 
 6 class UserController  extends  BaseController{
 7     。。。
 8     。。。
 9     。。。
10 
11     /**
12      * 登录操作: 校验登录信息
13      */
14     public function dlogin()
15     {
16         //接收登录信息
17         $data = array();
18         $data['username'] = trim($_POST['username']);
19         $data['pwd'] = trim($_POST['pwd']);
20 
21         //实例化模型,调用模型方法
22         //$model = new UserModel();
23         //$result = $model->checkLoginInfo($data);
24         //替换上面两行
25         $result = FactoryModel::M('User')->checkLoginInfo($data);
26 
27         //跳转提示
28         if($result){
29             $this->msg('登录成功!', '?a=index',3);
30         } else {
31             $this->msg('用户名或密码不正确!!');
32         }
33     }
34 }

4) 测试程序运行,  登录测试结果与前面一致。暂时先提交代码

1 git add -A
2 git commit -m "完成模型工厂类"

目录结构优化

   思路

 多个平台(模块):前后,后台
        MVC结构分平台
            C:  Controllers/Home      Controllers/Admin  .....
            V:  Views/Home                Views/Admin  .....
            M:   操作数据表一般模块共用
        公共资源目录Public: Public/Home  Public/Admin  .....
     目录结构变化,所有载入类,视图的路径做相应变化 

  代码实现

1)操作步骤

php源码建博客3--区分平台的MVC结构
1)目录构建: 
step 1: 根目录下创建目录App, 将Model目录,View目录,Controller目录放大App目录下
	既根目录只有: App/ Public/ Frame/  index.php

step 2: 在Controller目录中,创建Back目录和Home目录。将UserController控制器类文件放入Home目录中

step 3: 在View目录中,创建Back目录和Home目录。将login.html文件放入Home目录中

step 4: 在Public目录中,创建Back目录,Home目录,Plugins目录。将js,images,css目录放入Home目录中,公共插件放入对应的Plugins目录中

2)文件引入修改:
step 5: index.php入口文件对UserCotroller类的引入路径修改

step 6:UserController类中对视图login.html的include路径的修改

step 7: 视图login.html中对css和js路径的引入
操作步骤思路

2) 具体代码修改操作

  入口文件引入类路径修改【index.php】 主要是用户模型类和用户控制器类路径引入修改

php源码建博客3--区分平台的MVC结构
 1 <?php
 2 /**
 3  * 入口文件
 4  */
 5 require_once 'Frame/Db.class.php';  //数据库操作类
 6 require_once 'Frame/BaseModel.class.php';  //基础模型类
 7 require_once 'App/Model/UserModel.class.php';
 8 
 9 require_once 'Frame/FactoryModel.class.php';//模型工厂类
10 
11 require_once 'Frame/BaseController.class.php';  //基础控制器类
12 require_once 'App/Controller/Home/UserController.class.php';
13 
14 //实例化控制器
15 $userCtr = new UserController();
16 
17 $a = !empty($_GET['a']) ? $_GET['a'] : 'login';
18 
19 $userCtr -> $a();
入口文件引入类的修改

  用户控制器类对登录表单视图路径引入的修改 【App/Controller/Home/UserController.class.php】

php源码建博客3--区分平台的MVC结构
 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 "App/View/Home/User/login.html";
14     }
15 。。。
16 。。。
17 。。。
用户控制器展示登录界面修改

  登录表单视图 【App/View/Home/User/login.html】 对静态资源路径的修改

php源码建博客3--区分平台的MVC结构
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>登录</title>
 6     <link rel="stylesheet" type="text/css" href="public/plugins/layui/css/layui.css">
 7     <link rel="stylesheet" type="text/css" href="public/Home/css/style.css">
 8 </head>
 9 。。。
10 。。。
11 。。。
12 <script type="text/javascript" src="public/plugins/layui/layui.js"></script>
13 <script>
14     layui.use('form', function(){
15         var form = layui.form;
16     });
17 </script>
18 </body>
19 </html>
登录表单视图

  效果及提交代码

 php源码建博客3--区分平台的MVC结构提交保存代码

1 git add -A
2 git commit -m "目录结构优化"

区分平台(前台,后台....)

   思路

  实现根据平台的不同进行不同的操作

  用户点击页面请求,随着url发送3个参数: p=平台&c=控制器&a=动作
       入口文件接收get数据就可以知道:  平台, 控制器, 动作

  代码实现

1) 操作步骤:

php源码建博客3--区分平台的MVC结构
1)入口文件平台区分:
    step 1:  入口-登录页面提交的action="?p=Home&c=User&a=dlogin"

    step 2:  入口文件index.php  接收$_GET

    step 3:  登录判断成功跳转地址: $this->msg('登录成功!', '?p=Admin&c=Index&a=index',3);
	
2) 后台首页:
     step 1:   静态css,js,img文件放置 Public/Admin/

     step 2:   创建后台首页控制器类,
			index() 载入后台首页视图文件

     step 3:  View/Admin/Index/index.html 修正css等静态文件路
操作步骤思路

2)登录表单提交action=“?p=Home&c=User&a=dlogin”    【App/View/Home/User/login.html】

php源码建博客3--区分平台的MVC结构
 1 <!DOCTYPE html>
 2 <html lang="zh-CN">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>登录</title>
 6     <link rel="stylesheet" type="text/css" href="public/plugins/layui/css/layui.css">
 7     <link rel="stylesheet" type="text/css" href="public/Home/css/style.css">
 8 </head>
 9 <body>
10 <div class="container">
11     <div class="content">
12         <form action="?p=Home&c=User&a=dlogin" class="layui-form" method="post">
13 。。。。。。。
登录表单form提交action修改

3) 入口文件区分平台 【index.php】

<?php
/**
 * 入口文件
 */

$p = !empty($_GET['p']) ? $_GET['p'] : 'Home';  //平台
$c = !empty($_GET['c']) ? $_GET['c'] : 'User';  //控制器
$a = !empty($_GET['a']) ? $_GET['a'] : 'login'; //动作

require_once 'Frame/Db.class.php';  //数据库操作类
require_once 'Frame/BaseModel.class.php';  //基础模型类
require_once 'App/Model/UserModel.class.php';

require_once 'Frame/FactoryModel.class.php';//模型工厂类

require_once 'Frame/BaseController.class.php';  //基础控制器类
require_once 'App/Controller/'.$p.'/'.$c.'Controller.class.php';

$ctr = $c."Controller";
//实例化控制器
$userCtr = new $ctr();

$userCtr -> $a();

用户控制器登录操作,登录成功跳转到后台首页 【App/Controller/Home/UserController.class.php】

php源码建博客3--区分平台的MVC结构
 1 <?php
 2 /**
 3  * UserController.class.php 用户控制器
 4  */
 5 
 6 class UserController  extends  BaseController{
 7 。。。
 8 。。。
 9 。。。
10  /**
11      * 登录操作: 校验登录信息
12      */
13     public function dlogin()
14     {
15         //接收登录信息
16         $data = array();
17         $data['username'] = trim($_POST['username']);
18         $data['pwd'] = trim($_POST['pwd']);
19 
20         //实例化模型,调用模型方法
21         $result = FactoryModel::M('User')->checkLoginInfo($data);
22 
23         //跳转提示
24         if($result){
25             $this->msg('登录成功!', '?p=Admin&c=Index&a=index',3);
26         } else {
27             $this->msg('用户名或密码不正确!!');
28         }
29     }
30 }
登录操作成功后跳转路径修改

  测试

 1)模板准备: 

      准备后台视图模板程序。可以自己写前端视图模板程序,也可以到网上下载别人写好的前端模板,如到 模板之家  选择所需求的 前台,后台模板 

      寻找模板:

   2) 将后台模板视图的静态资源文件(如 js, css,image)拷贝到 【Public/admin/】目录下

   3) 创建后台首页控制器 【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 'App/View/Admin/Index/index.html';
14     }
15 }

4) 创建后台首页视图 【App/View/Admin/Index/index.html】

php源码建博客3--区分平台的MVC结构
  1 <!doctype html>
  2 <html>
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>后台管理</title>
  6     <link rel="stylesheet" type="text/css" href="./Public/Admin/css/common.css"/>
  7     <link rel="stylesheet" type="text/css" href="./Public/Admin/css/main.css"/>
  8     <script type="text/javascript" src="./Public/Admin/js/libs/modernizr.min.js"></script>
  9     <script type="text/javascript" src="./Public//home/js/jquery1.42.min.js"></script>
 10 </head>
 11 <body>
 12 
 13 
 14 <div class="topbar-wrap white">
 15     <div class="topbar-inner clearfix">
 16         <div class="topbar-logo-wrap clearfix">
 17             <h1 class="topbar-logo none"><a href="index.html" class="navbar-brand">后台管理</a></h1>
 18             <ul class="navbar-list clearfix">
 19                 <li><a class="on" href="?p=back">首页</a></li>
 20                 <li><a href="./" target="_blank">网站首页</a></li>
 21             </ul>
 22         </div>
 23         <div class="top-info-wrap">
 24             <ul class="top-info-list clearfix">
 25                 <li><a href="">user1</a></li>
 26                 <li><a href="?p=back&c=Index&a=ChangePswd">修改密码</a></li>
 27                 <li><a href="?c=User&a=Logout">退出</a></li>
 28             </ul>
 29         </div>
 30     </div>
 31 </div>
 32 <div class="container clearfix">
 33 
 34     <!--左侧菜单栏-->
 35 
 36     <!--左侧菜单栏 begin-->
 37     <div class="sidebar-wrap">
 38         <div class="sidebar-title">
 39             <h1>菜单</h1>
 40         </div>
 41         <div class="sidebar-content">
 42             <ul class="sidebar-list">
 43                 <li>
 44                     <a href="#"><i class="icon-font">&#xe003;</i>常用操作</a>
 45                     <ul class="sub-menu">
 46                         <li><a href="#"><i class="icon-font">&#xe008;</i>分类管理</a></li>
 47                         <li><a href="#"><i class="icon-font">&#xe005;</i>博文管理</a></li>
 48                         <li><a href="#"><i class="icon-font">&#xe012;</i>评论管理</a></li>
 49                         <li><a href="#"><i class="icon-font">&#xe052;</i>友情链接</a></li>
 50                     </ul>
 51                 </li>
 52                 <li>
 53                     <a href="#"><i class="icon-font">&#xe018;</i>系统管理</a>
 54                     <ul class="sub-menu">
 55                         <li><a href="#"><i class="icon-font">&#xe017;</i>系统设置</a></li>
 56                         <li><a href="#"><i class="icon-font">&#xe046;</i>数据备份</a></li>
 57                         <li><a href="#"><i class="icon-font">&#xe045;</i>数据还原</a></li>
 58                     </ul>
 59                 </li>
 60             </ul>
 61         </div>
 62     </div>
 63     <!--左侧菜单栏 begin-->
 64 
 65     <!--右侧主操作区-->
 66     <div class="main-wrap">
 67         <div class="crumb-wrap">
 68             <div class="crumb-list">
 69                 <i class="icon-font">&#xe06b;</i>
 70                 <span>欢迎使用博客后台管理系统。</span>
 71             </div>
 72         </div>
 73         <div class="result-wrap">
 74             <div class="result-title">
 75                 <h1>系统基本信息</h1>
 76             </div>
 77             <div class="result-content">
 78                 <ul class="sys-info-list">
 79                     <li>
 80                         <label class="res-lab">操作系统</label><span class="res-info">WINNT</span>
 81                     </li>
 82                     <li>
 83                         <label class="res-lab">运行环境</label><span class="res-info">Apache/2.2.21 (Win64) PHP/5.3.10</span>
 84                     </li>
 85                     <li>
 86                         <label class="res-lab">PHP运行方式</label><span class="res-info">apache2handler</span>
 87                     </li>
 88                     <li>
 89                         <label class="res-lab">模板版本</label><span class="res-info">v-0.1</span>
 90                     </li>
 91                     <li>
 92                         <label class="res-lab">上传附件限制</label><span class="res-info">2M</span>
 93                     </li>
 94                     <li>
 95                         <label class="res-lab">北京时间</label>
 96                         <span class="res-info" id='nowtime'><?php echo date('Y年m月d日 H:i:s',time()); ?></span>
 97                     </li>
 98                     <li>
 99                         <label class="res-lab">服务器域名</label><span class="res-info"><span id="host">localhost</span></span>
100                     </li>
101                 </ul>
102             </div>
103         </div>
104     </div>
105     <!--/main-->
106     <script >
107         $(function(){
108             $("#nowtime").css({color:'red'});
109             $("#host").html(location.host);
110             window.setInterval('ShowTime()',1000);
111         });
112         function ShowTime(){
113             var t = new Date();
114             var str = t.getFullYear() + '年';
115             str += t.getMonth()+1 + '月';
116             str += t.getDate()-1 + '日 ';
117             str += t.getHours() + ':';
118             str += t.getMinutes() + ':';
119             str += t.getSeconds() + '';
120             $("#nowtime").html(str);
121         }
122     </script>
123 </div>
124 
125 </body>
126 </html>
后台首页视图

  效果及提交代码

  代码提交,推送

1 $  git add -A
2 $  git commit -m "区分平台,实现后台首页"
3 $  git checkout master
4 $  git merge 'folder-model-app'
5 $  git push origin master

小结: 根据平台进一步优化目录结构,制作模型的单例工厂,实现后台首页

提出问题

  1. 项目中可以看到 include或require的文件路径很长,容易出错,也不便于使用  ==> 如何更加简单引入且不易出错

     2. 写一个类,就要到入口文件引入一次, 比较麻烦  ==>  如何实现自动加载类

  3. 随着类的引入增加,入口文件代码量会越来越大  ==>  如何 封装,简化入口文件

  4. 现在项目中任何一个目录,都可以随意访问  ==> 如何加强安全访问,限制目录的访问

下一步:常量使用,自动加载类实现,入口封装,限制目录访问