主要:

  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. Linux 虚拟机中配置 GNOME + VNC

    需求描述 在特定的需求下,需要用到 Linux 的图形化界面,但是 Azure 平台提供的虚拟机默认没有开放远程图形化登陆的功能.以下解决方案,提供了市面上非常流行的 GNOME + VNC 的组合来 ...

  2. @vue-cli3配合element和scss打包的配置

    @vue-cli3配合element和scss打包的配置 标签(空格分隔): Vue 使用@vue-cli3初始化项目,且使用ElementUI,然后按照官方文档自定义主题. 自己的scss全局变量文 ...

  3. Hadoop学习---Zookeeper+Hbase配置学习

    软件版本号: JDK:jdk-8u45-linux-i586.tar.gz Zookeeper:zookeeper-3.4.6 Hbase:hbase-1.0.0-bin 一.JDK版本更换 由于之前 ...

  4. slider.js 滑动和点击事件在firefox下报错 event is not defined

    在使用layui的slider滑块控件的时候,firefox遇到了event is not defined 的情况.追究原因是因为layui的layui.js 的滑块功能依赖于silder.js,而官 ...

  5. 远程计算机或设备将不接受连接,IE无法上网

    遇到一个奇葩问题,IE浏览器突然不能上网了,但是其他浏览器可以,QQ什么的也都正常,只有IE是出现:远程计算机或设备将不接受连接 这个问题,网上找了很多答案都没用,什么设置WINS,允许远程访问,取消 ...

  6. 「bzoj 3944: Sum」

    题目 杜教筛板子了 #include<iostream> #include<cstring> #include<cstdio> #include<cmath& ...

  7. GitBash初始目录的修改

    GitBash初始目录是定为到用户目录的,例如: 所以,每次打开都要手动调试到仓库所在的目录,可以通过修改目标和起始位置来定位到仓储文件夹下. 再次打开git,完美~~

  8. bagging 和boosting的概念和区别

    1.先弄清楚模型融合中的投票的概念 分为软投票和硬投票,硬投票就是几个模型预测的哪一类最多,最终模型就预测那一类,在投票相同的情况下,投票结果会按照分类器的排序选择排在第一个的分类器结果.但硬投票有个 ...

  9. 【绝迹篇】C#RSA算法实现

    当下最流行的RSA加密算法,只有公钥和私钥同时拥有才能破解加密信息,RSA加密算法的出现有利于数据安全性传输 1.C#中自带RSACryptoServiceProvider类可以让你很好的生成XML格 ...

  10. Ant自动化打多渠道包,Android批量打包提速

    Eclipse用起来虽然方便,但是编译打包android项目还是比较慢,尤其将应用打包发布到各个渠道时,用Eclipse手动打包各种渠道包就有点不切实际了,这时候我们用到Ant帮我们自动编译打包了. ...