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

Posted yangp67

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php源码建博客2--实现单入口MVC结构相关的知识,希望对你有一定的参考价值。

主要:

  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
/**
 * 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

技术分享图片
 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】

技术分享图片
  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】

技术分享图片
 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

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

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
















以上是关于php源码建博客2--实现单入口MVC结构的主要内容,如果未能解决你的问题,请参考以下文章

框架结构

php源码建博客1--搭建站点-实现登录页面

php源码建博客5--建库建表-配置文件-错误日志

PHP项目MVC单一入口原理

php实现日志管理(记录用户操作)原理

简述MVC思想 与PHP如何实现MVC