主要:

  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)准备: 创建分支

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

  2) 创建目录结构:

      MVC目录: Model/  Controller/   View/

        静态资源目录: Public/

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

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

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

 <?php
/**
* 入口文件
*/
header("content-type:text/html;charset=utf-8"); require_once('Model/UserModel.class.php');
require_once 'Controller/UserController.class.php'; //实例化控制器
$userCtr = new UserController(); $a = !empty($_GET['a']) ? $_GET['a'] : 'login'; $userCtr -> $a();

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

 <?php
/**
* UserController.class.php 用户控制器
*/ class UserController {
/**
* 展示登录界面
* @access public
*/
public function login()
{
include "View/login.html";
} /**
* 登录操作: 校验登录信息
*/
public function dlogin()
{
//接收登录信息
$data = array();
$data['username'] = trim($_POST['username']);
$data['pwd'] = trim($_POST['pwd']); //实例化模型,调用模型方法,校验用户名和密码
$model = new UserModel();
$result = $model->checkLoginInfo($data); //结果提示信息
if($result){
exit('登录成功');
} else {
echo "用户名或密码不正确!";
header('refresh:3; url=?');
}
}
}

  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

 <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>登录</title>
<link rel="stylesheet" type="text/css" href="public/layui/css/layui.css">
<link rel="stylesheet" type="text/css" href="public/css/style.css">
</head>
<body>
<div class="container">
<div class="content">
<form action="?a=dlogin" class="layui-form" method="post">
<div class="layui-form-item">
<h2>登录</h2>
</div><hr> <div class="layui-form-item">
<label class="layui-form-label">用户名:</label>
<div class="layui-input-block">
<input type="text" name="username" class="layui-input" required lay-verify="required" placeholder="请输入用户名" autocomplete="off" >
</div>
</div> <div class="layui-form-item">
<label class="layui-form-label">密&nbsp;&nbsp;&nbsp;码:</label>
<div class="layui-input-block">
<input type="password" name="pwd" required lay-verify="required" placeholder="请输入密码" class="layui-input">
</div>
</div> <div class="layui-form-item">
<div class="layui-input-block">
<button lay-submit class="layui-btn">登录</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
<script type="text/javascript" src="public/layui/layui.js"></script>
<script>
layui.use('form', function(){
var form = layui.form;
});
</script>
</body>
</html>

点击查看登录视图源码

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

数据库工具类制作

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

实现单例

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

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

【Frame/Db.class.php】

 <?php
/**
* Db.class.php 数据库操作工具类
* @author young
*/ class Db
{
private $host; //主机
private $user; //用户名
private $pwd; //密码
private $port; //端口
private $charset; //编码
private $dbname; //数据库 private $link=null; //存储数据库资源
private static $instance=null; //存储本类实例对象 /**
* 构造方法: 保存数据库连接信息,连接数据库
* @access private
* @param array $conf 数据库连接信息
*/
private function __construct($conf)
{
$this->host = !empty($conf['host']) ? $conf['host'] : 'localhost';
$this->user = !empty($conf['user']) ? $conf['user'] : 'root';
$this->pwd = !empty($conf['pwd']) ? $conf['pwd'] : 'root';
$this->port = !empty($conf['port']) ? $conf['port'] : '3306';
$this->charset = !empty($conf['charset']) ? $conf['charset'] : 'utf8';
$this->dbname = !empty($conf['dbname']) ? $conf['dbname'] : 'web'; $this->connect();
} /**
* 连接数据库,设置编码,选库
* @access private
*/
private function connect()
{
$this->link = @ mysql_connect("{$this->host}:{$this->port}", "$this->user", "$this->pwd") or die('连接失败!'.mysql_error());
$this->setCharset($this->charset);
$this->useDb($this->dbname);
}
/**
* 设置字符便
* @access public
* @param string $char 字符编码
*/
public function setCharset($char)
{
$this->query("set names $char");
}
/**
* 选择数据库
* @access public
* @param string $dbname 数据库名称
*/
public function useDb($dbname)
{
$this->query("use $dbname");
} /**
* 执行sql语句
* @param string $sql sql语句
* @return mixed
*/
private function query($sql)
{
$result = mysql_query($sql, $this->link);
if(false === $result) {
echo "<p>sql执行失败!<br>";
echo "<br>失败语句:".$sql;
echo "<br>错误代号".mysql_errno();
echo "<br>错误提示: ".mysql_error()."</p>";
exit();
}
return $result;
} /**
* 获取本类实例
* @access public
* @param array $conf 数据库连接信息
* @return object 本类的单例对象
*/
public static function getDb($conf)
{
if(false === (static::$instance instanceof static)){
static::$instance = new static($conf);
}
return static::$instance;
}
/**
* 禁止克隆
*/
public function __clone()
{ }
/**
* 关闭数据库连接
* @access public
*/
public function closeDb()
{
mysql_close($this->link);
} public function exec($sql)
{
$result = $this->query($sql);
return $this->affectedRows(); }
/**
* 受影响的行数
* @return int 返回受影响的行数
*/
private function affectedRows()
{
return mysql_affected_rows($this->link);
} /**
* 执行 “返回一行数据”的查询
* @param string $sql sql语句
* @return array 一维数组(一行)
*/
public function getOneRow($sql)
{
$result = $this->query($sql);
$data = mysql_fetch_assoc($result);
mysql_free_result($result);
return $data;
}
/**
* 执行 "返回多行数据" 的查询
* @param string $sql sql语句
* @return array 二维数组
*/
public function getAllRows($sql)
{
$result = $this->query($sql);
$data = array();
while($row = mysql_fetch_assoc($result)){
$data[] = $row;
}
mysql_free_result($result);
return $data;
}
/**
* 执行“获取一个数据”的查询
* @param string $sql sql语句
* @return mixed 标量数据值
*/
public function getOneData($sql)
{
$result = $this->query($sql);
$data = mysql_fetch_row($result);
mysql_free_result($result);
return $data[0];
} /**
* 上次insert时的自增长id值
* @return int insert时的id值
*/
public function getInsertId()
{
return mysql_insert_id($this->link);
} /**
* 序列化时,对指定数据进行序列化
* @return array 指定进行序列化的数据
*/
public function __sleep()
{
return array('host', 'port', 'user', 'pass','charset', 'dbname');
}
/**
* 反序列化时,使用相应数据连接数据库
*/
public function __wakeup()
{
$this->connect(); //连接数据库
}
/**
* 自动生成insert语句或update语句
* @param array $data insert或update的数据
* @param string $table 操作的数据表
* @param string $act 是update还是insert操作
* @param string $where where条件 如 id=2 如果是update必须加,否则不执行直接返回false
* @return bool 执行insert与update的结果
*/
public function autoExecute($data, $table, $act='insert', $where='')
{
if($act == 'insert') {
$sql = "insert into ".$table."(";
$sql .=implode(",", array_keys($data));
$sql .= ") values ('";
$sql .= implode("','", array_values($data));
$sql .= "')"; $res = $this->exec($sql);
return $this->getInsertId(); } else if($act == 'update') {
if(!$where) { return false; }
$sql = 'update '.$table.' set ';
foreach ($data as $k => $v) {
$sql .= $k."='".$v."',";
}
$sql = substr($sql, 0, -1);
$sql .= ' where '.$where; return $this->exec($sql);
} else {
return false;
} }
}

点击查看工具类

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

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

 <?php

 /**
* BaseModel.class.php 基础模型类
* 连接数据库
*/
class BaseModel
{
protected $db = null;
/**
* 构造方法: 实例化数据库类
* @access public
* @param array $config 数据库配置信息
*/
function __construct(array $config=null)
{
$conf = array(
'host'=>'localhost',
'user'=>'root',
'pwd'=>'root',
'port'=>'3306',
'charset'=>'utf8',
'dbname'=>'web',
);
$conf = empty($config)? $conf : array_merge($conf,$config);
$this->db = Db::getDb($conf);
}
}

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

    统一了编码

    提示信息跳转

 <?php
/**
* BaseController.class.php 公共控制器
* @author young
*/ class BaseController
{
/**
* 统一编码utf8
*/
public function __construct()
{
header("content-type:text/html;charset=utf-8");
session_start();
} /**
* 跳转提示
* @access public
* @param string $msg 跳转提示信息
* @param string $url 跳转的地址
* @param integer $time 等待时间 秒数
*/
public function msg($msg='', $url='?', $time=3)
{
echo "<div><a href='$url'>返回</a></div>页面将在{$time}秒之后跳转!!";
header("refresh: $time; url=$url");
exit("<div><span style='color:red'>$msg</span></div>");
}
}

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

  【index.php】

 <?php
/**
* 入口文件
*/
require_once 'Frame/Db.class.php';
require_once 'Frame/BaseModel.class.php';
require_once('Model/UserModel.class.php');
require_once 'Frame/BaseController.class.php';
require_once 'Controller/UserController.class.php'; //实例化控制器
$userCtr = new UserController(); $a = !empty($_GET['a']) ? $_GET['a'] : 'login'; $userCtr -> $a();

点击查看入口文件

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

 <?php

 /**
* UserModel.class.php
* 用户模型类-操作表pbg_users
*/
class UserModel extends BaseModel
{
/**
* 检验登录信息
* @param array $data 用户提交的登录信息
* @return bool true-校验成功 false-校验失败
*/
public function checkLoginInfo($data)
{
$sql = "select id,username,pwd from pbg_users where username='{$data['username']}'";
$res = $this->db->getOneRow($sql);
return $res['pwd'] == md5($data['pwd']) ? : false;
}
}

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

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

 。。。。。。。
/**
* 登录操作: 校验登录信息
*/
public function dlogin()
{
//接收登录信息
$data = array();
$data['username'] = trim($_POST['username']);
$data['pwd'] = trim($_POST['pwd']); //实例化模型,调用模型方法
$model = new UserModel();
$result = $model->checkLoginInfo($data);
//跳转提示
if($result){
$this->msg('登录成功!', '?a=index',3);
} else {
$this->msg('用户名或密码不正确!!');
}
}

合并保存并推送git

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

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

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

php源码建博客2--实现单入口MVC结构的更多相关文章

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

    主要: 模型单例工厂 目录结构优化 区分平台(前台,后台....) --------------文件结构:-------------------------------------- blog├─Ap ...

  2. php源码建博客4--实现MVC结构微型框架

    主要: 常量优化路径 自动加载类 优化入口文件 安全访问项目目录 --------------文件结构:-------------------------------------- blog├─App ...

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

    主要: 整理框架 建库建表 配置文件类 错误日志记录 --------------本篇后文件结构:-------------------------------------- blog ├─App │ ...

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

    主要: 站点搭建 实现登录页面 分析及改进 站点搭建 1)  在apache安装目录下: [conf\extra\httpd-vhosts.conf]加入站点配置 <VirtualHost *: ...

  5. spark 源码阅读博客

    http://blog.csdn.net/oopsoom/article/details/38257749

  6. 鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main | 百篇博客分析OpenHarmony源码 | v51.04

    百篇博客系列篇.本篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应用程序入口并不是main | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | ...

  7. 00-django | 01-构建博客目录

    00-django | 01-构建博客目录 python Django 创建blog 进入到 manage.py 文件所在的目录(即项目根目录)下,运行 pipenv run python manag ...

  8. 用hugo建博客的记录 · 老张不服老

    前后累计折腾近6个小时,总算把搭建hugo静态博客的整个过程搞清楚了.为什么用了这么久?主要还是想偷懒,不喜欢读英文说明.那就用中文记录一下过程吧.还是中文顺眼啊. 某日发现自己有展示些东西给外网的需 ...

  9. C博客作业01——分支,顺序结构

    C博客作业01--分支,顺序结构 0.展示PTA总分 1本章学习内容 1.1学习内容总结 1)格式化输出函数printf(),scanf(). 它是什么? 对于初学者而言,一开始了解接触它们,只是被硬 ...

随机推荐

  1. [PE格式分析] 4.IMAGE_FILE_HEADER

    源代码如下: typedef struct _IMAGE_FILE_HEADER { +04h WORD Machine; // 运行平台 +06h WORD NumberOfSections; // ...

  2. 用两个栈实现队列(C++ 和 Python 实现)

    (说明:本博客中的题目.题目详细说明及参考代码均摘自 “何海涛<剑指Offer:名企面试官精讲典型编程题>2012年”) 题目 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数 a ...

  3. 从Linux访问Windows共享目录

    今天装备用VMWare装台Linux服务器来学习Oracle数据库,由于安装包是下载到本地的Windows系统,需要拷贝到Linux虚机里面去.搞了半天.想到虚机网络设成桥接,然后访问.百度了一下.最 ...

  4. Dapper进行增删改查 z

    http://www.cnblogs.com/huangkaiyan10/p/4640548.html 项目背景 前一段时间,开始做一个项目,在考虑数据访问层是考虑技术选型,考虑过原始的ADO.NET ...

  5. windows线程时间打印

    https://blog.csdn.net/xingcen/article/details/70084029

  6. Go语言(三)反射机制

    package main import( "fmt" "reflect" ) func main(){ // iterate through the attri ...

  7. 轻松bypass360网站卫士WAFSQL注入防护

    随便网上找了一个网站,只是测试一下,没有干非法的事情! code 区域 http://www.py-guanyun.com/CompHonorBig.asp?id=49 code 区域 http:// ...

  8. 应用服务&领域服务

    应用服务&领域服务 DDD理论学习系列——案例及目录 1. 引言 单从字面理解,不管是领域服务还是应用服务,都是服务.而什么是服务?从SOA到微服务,它们所描述的服务都是一个宽泛的概念,我们可 ...

  9. dia无法输入中文的解决

    安装dia后无法输入中文,解决如下: 修改/usr/bin/dia #dia-normal --integrated "$@" dia-normal "$@"

  10. Python深入学习之《Fluent Python》 Part 1

    Python深入学习之<Fluent Python> Part 1 从上个周末开始看这本<流畅的蟒蛇>,技术是慢慢积累的,Python也是慢慢才能写得优雅(pythonic)的 ...