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

php源码建博客2--实现单入口MVC结构

程序员文章站 2022-06-24 09:37:51
主要: 一,MVC目录结构 1)准备: 创建分支 2) 创建目录结构: MVC目录: Model/ Controller/ View/ 静态资源目录: Public/ 3) 创建项目入口文件 【index.php】 拷贝原login.php的编码header(...) 引入创建的控制器UserCon ......

主要:

  1. MVC目录结构
  2. 数据库工具类制作
  3. 创建公共模型类和公共控制器类
--------------文件结构:--------------------------------------
blog
├─index.php  入口文件
├─Model 模型
│  └─UserModel.class.php 用户模型类
├─View 视图
│  └─login.html  登录表单页面
├─Controller 控制器
│  └─UserController.class.php 用户控制器
├─Frame 公共使用的类
│   ├─BaseModel.class.php 数据库连接类
│   ├─BaseController.class.php 控制器公共操作(设置编码,信息跳转)
│   └─Db.class.php 数据库操作工具类
└─Public   静态公共文件(js,css,images)
    ├─js/   js文件
    ├─css/  css样式文件
    └─images img图片 -----------------------------------------------------------------

一,MVC目录结构

  1)准备: 创建分支

1 $ git checkout master
2 $ git checkout -b "mvc-dbtools-base"

  2) 创建目录结构:

      MVC目录: Model/  Controller/   View/  

        静态资源目录: Public/

  3) 创建项目入口文件  【index.php】

    拷贝原login.php的编码header(...)

    引入创建的控制器UserController 和 模型 UserModel

 1 <?php
 2 /**
 3  * 入口文件
 4  */
 5 header("content-type:text/html;charset=utf-8");
 6 
 7 require_once('Model/UserModel.class.php');
 8 require_once 'Controller/UserController.class.php';
 9 
10 //实例化控制器
11 $userCtr = new UserController();
12 
13 $a = !empty($_GET['a']) ? $_GET['a'] : 'login';
14 
15 $userCtr -> $a();

  4)  创建控制器UserController   【Controller/UserController.class.php】

 1 <?php
 2 /**
 3  * UserController.class.php 用户控制器
 4  */
 5 
 6 class UserController {
 7     /**
 8      * 展示登录界面
 9      * @access public
10      */
11     public function login()
12     {
13         include "View/login.html";
14     }
15 
16     /**
17      * 登录操作: 校验登录信息
18      */
19     public function dlogin()
20     {
21         //接收登录信息
22         $data = array();
23         $data['username'] = trim($_POST['username']);
24         $data['pwd'] = trim($_POST['pwd']);
25 
26         //实例化模型,调用模型方法,校验用户名和密码
27         $model = new UserModel();
28         $result = $model->checkLoginInfo($data);
29 
30         //结果提示信息
31         if($result){
32             exit('登录成功');
33         } else {
34             echo "用户名或密码不正确!";
35             header('refresh:3; url=?');
36         }
37     }
38 }

  5)  创建用户模型类UserModel  【Model/UserModel.class.php】

    实现方法:checkLoginInfo() 检验用户名和密码

php源码建博客2--实现单入口MVC结构
<?php
/**
 * UserModel.class.php
 *     用户模型类-操作表pbg_users
 */
class UserModel
{
    /**
     * 检验登录信息
     * @param  array $data 用户提交的登录信息
     * @return bool       true-校验成功 false-校验失败
     */
    public function checkLoginInfo($data)
    {
        //连接数据库
        $conn = @mysql_connect('localhost','root','root') or die('连接数据库失败!');
        mysql_query('set names utf8',$conn);
        mysql_query('use web',$conn);

        //查询数据库
        $sql = "select username,pwd from pbg_users where username='{$data['username']}'";
        $res = mysql_query($sql,$conn);

        //登录结果提示信息
        if($res !== false){
            $user = mysql_fetch_array($res);
            if( $user['pwd'] == md5($data['pwd']) ){
                return true;
            }
        }
        return false;
    }
}
查看用户模型类

  6)登录视图:【view/login.html】

    引入路径的修正,

    表单提交action修正:  action=?a=dlogin

php源码建博客2--实现单入口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/layui/css/layui.css">
 7     <link rel="stylesheet" type="text/css" href="public/css/style.css">
 8 </head>
 9 <body>
10 <div class="container">
11     <div class="content">
12         <form action="?a=dlogin" class="layui-form" method="post">
13             <div class="layui-form-item">
14                 <h2>登录</h2>
15             </div><hr>
16 
17             <div class="layui-form-item">
18                 <label class="layui-form-label">用户名:</label>
19                 <div class="layui-input-block">
20                     <input type="text" name="username" class="layui-input" required  lay-verify="required"  placeholder="请输入用户名" autocomplete="off" >
21                 </div>
22             </div>
23 
24             <div class="layui-form-item">
25                 <label class="layui-form-label">密&nbsp;&nbsp;&nbsp;码:</label>
26                 <div class="layui-input-block">
27                     <input type="password" name="pwd" required lay-verify="required" placeholder="请输入密码"  class="layui-input">
28                 </div>
29             </div>
30 
31             <div class="layui-form-item">
32                 <div class="layui-input-block">
33                     <button  lay-submit class="layui-btn">登录</button>
34                     <button type="reset" class="layui-btn layui-btn-primary">重置</button>
35                 </div>
36             </div>
37         </form>
38     </div>
39 </div>
40 <script type="text/javascript" src="public/layui/layui.js"></script>
41 <script>
42     layui.use('form', function(){
43         var form = layui.form;
44     });
45 </script>
46 </body>
47 </html>
点击查看登录视图源码

数据库连接操作都在模型中,可以提取出来制作数据库操作工具类

二,数据库工具类制作

数据库连接,设置编码,选择数据库

实现单例

获取一行数据getOneRow,  获取单个数组 getOneData, 获取多行getAllRows, 增删改 exec

自动生成insert 或 update语句 autoExecute()

【Frame/Db.class.php】

php源码建博客2--实现单入口MVC结构
  1 <?php 
  2  /**
  3   * Db.class.php 数据库操作工具类
  4   * @author young
  5   */
  6  
  7  class Db
  8  {
  9      private $host; //主机
 10      private $user; //用户名
 11      private $pwd; //密码
 12      private $port; //端口
 13      private $charset; //编码
 14      private $dbname; //数据库
 15 
 16      private $link=null; //存储数据库资源
 17      private static $instance=null; //存储本类实例对象
 18 
 19      /**
 20       * 构造方法: 保存数据库连接信息,连接数据库
 21       * @access private
 22       * @param array $conf 数据库连接信息
 23       */
 24      private function __construct($conf)
 25      {
 26          $this->host = !empty($conf['host']) ? $conf['host'] : 'localhost';
 27          $this->user = !empty($conf['user']) ? $conf['user'] : 'root';
 28          $this->pwd = !empty($conf['pwd']) ? $conf['pwd'] : 'root';
 29          $this->port = !empty($conf['port']) ? $conf['port'] : '3306';
 30          $this->charset = !empty($conf['charset']) ? $conf['charset'] : 'utf8';
 31          $this->dbname = !empty($conf['dbname']) ? $conf['dbname'] : 'web';
 32 
 33          $this->connect();
 34      }
 35 
 36      /**
 37       * 连接数据库,设置编码,选库
 38       * @access private
 39       */
 40      private function connect()
 41      {
 42          $this->link = @ mysql_connect("{$this->host}:{$this->port}", "$this->user", "$this->pwd") or die('连接失败!'.mysql_error());
 43          $this->setCharset($this->charset);
 44          $this->useDb($this->dbname);
 45      }
 46      /**
 47       * 设置字符便
 48       * @access public
 49       * @param string $char 字符编码
 50       */
 51      public function setCharset($char)
 52      {
 53          $this->query("set names $char");
 54      }
 55      /**
 56       * 选择数据库
 57       * @access public
 58       * @param string $dbname 数据库名称
 59       */
 60      public function useDb($dbname)
 61      {
 62          $this->query("use $dbname");
 63      }
 64 
 65      /**
 66       * 执行sql语句
 67       * @param  string $sql sql语句
 68       * @return mixed
 69       */
 70      private function query($sql)
 71      {
 72          $result = mysql_query($sql, $this->link);
 73          if(false === $result) {
 74              echo "<p>sql执行失败!<br>";
 75              echo "<br>失败语句:".$sql;
 76              echo "<br>错误代号".mysql_errno();
 77              echo "<br>错误提示: ".mysql_error()."</p>";
 78              exit();
 79          }
 80          return $result;
 81      }
 82 
 83      /**
 84       *  获取本类实例
 85       * @access public
 86       * @param  array $conf 数据库连接信息
 87       * @return  object     本类的单例对象
 88       */
 89      public static function getDb($conf)
 90      {
 91          if(false === (static::$instance instanceof static)){
 92              static::$instance = new static($conf);
 93          }
 94          return static::$instance;
 95      }
 96      /**
 97       * 禁止克隆
 98       */
 99      public function __clone()
100      {
101      
102      }
103      /**
104       * 关闭数据库连接
105       * @access public
106       */
107      public function closeDb()
108      {
109          mysql_close($this->link);
110      }
111 
112      public function exec($sql)
113      {
114          $result = $this->query($sql);
115          return $this->affectedRows();
116 
117      }
118      /**
119       * 受影响的行数
120       * @return int 返回受影响的行数
121       */
122      private function affectedRows()
123      {
124          return mysql_affected_rows($this->link);
125      }
126 
127      /**
128       * 执行 “返回一行数据”的查询
129       * @param  string $sql sql语句
130       * @return array      一维数组(一行)
131       */
132      public function getOneRow($sql)
133      {
134          $result = $this->query($sql);
135          $data = mysql_fetch_assoc($result);
136          mysql_free_result($result);
137          return $data;
138      }
139      /**
140       * 执行 "返回多行数据" 的查询
141       * @param  string $sql sql语句
142       * @return array      二维数组
143       */
144      public function getAllRows($sql)
145      {
146          $result = $this->query($sql);
147          $data = array();
148          while($row = mysql_fetch_assoc($result)){
149              $data[] = $row;
150          }
151          mysql_free_result($result);
152          return $data;
153      }
154      /**
155       * 执行“获取一个数据”的查询
156       * @param  string $sql sql语句
157       * @return mixed      标量数据值
158       */
159      public function getOneData($sql)
160      {
161          $result = $this->query($sql);
162          $data = mysql_fetch_row($result);
163          mysql_free_result($result);
164          return $data[0];
165      }
166 
167      /**
168       * 上次insert时的自增长id值
169       * @return int insert时的id值
170       */
171      public function getInsertId()
172      {
173          return mysql_insert_id($this->link);
174      }
175 
176      /**
177       * 序列化时,对指定数据进行序列化
178       * @return array 指定进行序列化的数据
179       */
180      public function __sleep()
181      {
182          return array('host', 'port', 'user', 'pass','charset', 'dbname');
183      }
184      /**
185       * 反序列化时,使用相应数据连接数据库
186       */
187      public function __wakeup()
188      {
189          $this->connect(); //连接数据库
190      }
191      /**
192     * 自动生成insert语句或update语句
193     * @param array      $data          insert或update的数据
194     * @param  string     $table        操作的数据表
195     * @param  string     $act           是update还是insert操作
196     * @param  string     $where      where条件 如 id=2  如果是update必须加,否则不执行直接返回false
197     * @return bool        执行insert与update的结果
198     */
199      public function autoExecute($data, $table, $act='insert', $where='')
200      {
201          if($act == 'insert') {
202              $sql = "insert into ".$table."(";
203              $sql .=implode(",", array_keys($data));
204              $sql .= ") values ('";
205              $sql .= implode("','", array_values($data));
206              $sql .= "')";
207 
208              $res = $this->exec($sql);
209               return $this->getInsertId();
210 
211          } else if($act == 'update') {
212              if(!$where) { return false; }
213              $sql = 'update '.$table.' set ';
214              foreach ($data as $k => $v) {
215                  $sql .= $k."='".$v."',";
216              }
217              $sql = substr($sql, 0, -1);
218              $sql .= ' where '.$where;
219 
220              return $this->exec($sql);
221          } else {
222              return false;
223          }
224 
225      }
226  }
点击查看工具类

三,创建公共模型类和公共控制器类

  1) 公共模型类【Frame/BaseModel.class.php】  获取数据库操作工具类实例

 1 <?php
 2 
 3 /**
 4  * BaseModel.class.php 基础模型类
 5  *     连接数据库
 6  */
 7 class BaseModel
 8 {
 9     protected $db = null;
10     /**
11      * 构造方法: 实例化数据库类
12      * @access public
13      * @param array $config  数据库配置信息
14      */
15     function __construct(array $config=null)
16     {
17         $conf = array(
18             'host'=>'localhost',
19             'user'=>'root',
20             'pwd'=>'root',
21             'port'=>'3306',
22             'charset'=>'utf8',
23             'dbname'=>'web',
24         );
25         $conf = empty($config)? $conf : array_merge($conf,$config);
26         $this->db = Db::getDb($conf);
27     }
28 }

  2) 公共控制器类【Frame/BaseController】 :

    统一了编码

    提示信息跳转

 1 <?php
 2 /**
 3  * BaseController.class.php  公共控制器
 4  * @author young
 5  */
 6 
 7 class BaseController
 8 {
 9     /**
10      * 统一编码utf8
11      */
12     public function __construct()
13     {
14         header("content-type:text/html;charset=utf-8");
15         session_start();
16     }
17 
18     /**
19      * 跳转提示
20      * @access public
21      * @param  string  $msg  跳转提示信息
22      * @param  string  $url  跳转的地址
23      * @param  integer $time 等待时间 秒数
24      */
25     public function msg($msg='', $url='?', $time=3)
26     {
27         echo "<div><a href='$url'>返回</a></div>页面将在{$time}秒之后跳转!!";
28         header("refresh: $time; url=$url");
29         exit("<div><span style='color:red'>$msg</span></div>");
30     }
31 }

  3)入口文件中引入工具类,基础模型和基础控制器类

  【index.php】

php源码建博客2--实现单入口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 require_once 'Frame/BaseController.class.php';
 9 require_once 'Controller/UserController.class.php';
10 
11 //实例化控制器
12 $userCtr = new UserController();
13 
14 $a = !empty($_GET['a']) ? $_GET['a'] : 'login';
15 
16 $userCtr -> $a();
点击查看入口文件

  4)用户模型类优化 【Model/UserModel.class.php】

 1 <?php
 2 
 3 /**
 4  * UserModel.class.php
 5  *     用户模型类-操作表pbg_users
 6  */
 7 class UserModel extends BaseModel
 8 {
 9     /**
10      * 检验登录信息
11      * @param  array $data 用户提交的登录信息
12      * @return bool       true-校验成功 false-校验失败
13      */
14     public function checkLoginInfo($data)
15     {
16         $sql = "select id,username,pwd from pbg_users where username='{$data['username']}'";
17         $res = $this->db->getOneRow($sql);
18         return $res['pwd'] == md5($data['pwd']) ? : false;
19     }
20 }

  5) 用户控制器登录操作,跳转提示优化

    使用公共控制器方法msg()

 1 。。。。。。。
 2     /**
 3      * 登录操作: 校验登录信息
 4      */
 5     public function dlogin()
 6     {
 7         //接收登录信息
 8         $data = array();
 9         $data['username'] = trim($_POST['username']);
10         $data['pwd'] = trim($_POST['pwd']);
11 
12         //实例化模型,调用模型方法
13         $model = new UserModel();
14         $result = $model->checkLoginInfo($data);
15         //跳转提示
16         if($result){
17             $this->msg('登录成功!', '?a=index',3);
18         } else {
19             $this->msg('用户名或密码不正确!!');
20         }
21     }

合并保存并推送git

1 $ git add -A
2 $ git commit -m "MVC结构,数据库操作类,基础模型类和基础控制器类制作"
3 $ git checkout master
4 $ git merge mvc-dbtools-base
5 $ git push origin master

小结: 优化目录结构,制作数据库操作类,基础模型类与基础控制器类使用

下一步: 模型类实现单例, 进一步优化目录结构,区分平台(如前台,后台)