主要:

  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. Nginx(持续更新中)

    Nginx介绍 -- 安装部署 -- 配置文件说明 --

  2. mac 修改MAC代码

    1.生成一个mac地址: openssl rand -hex | sed 's/\(..\)/\1:/g; s/.$//' 2.关闭无线 sudo /System/Library/PrivateFra ...

  3. redis3.2.8安装与简介

    Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的 ...

  4. 【Leetcode】【Medium】3Sum Closest

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  5. mysqldump导出sql文件中insert多行问题

    mysqldump为了加快导入导出,默认把数据都缩减在一行里面. 查看和修改不方便,为此,我们可以使用--skip-extended-insert选项来使导出的数据,是多行插入形式的. mysqldu ...

  6. 《C++ Primer Plus》读书笔记之二—复合类型

    二.第四章 复合类型  1.C-风格字符串:C-风格字符串具有一种特殊的性质:以空字符结尾,空字符被写成\0,其ASC||编码为0,用来标记字符串的结尾.例如: char dog[5]={'b','e ...

  7. msvcr100.dll问题描述及修复方式

    出现问题的大部分原因是因该文件被木马病毒破坏导致系统找不到此文件,出现错误提示框,想要解决此问题只需找到专业的DLL文件下载网站,下载该文件,复制到相应目录.即可解决.msvcr100.dll为Vis ...

  8. Code First TPH、TPT、TPC与继承类

    一.Table Per Hierarchy (TPH,默认) 每个层次结构共用一个表,类的每一个属性都必须是可空的. 1.默认行为 只建立一个表,把基类和子类中的所有属性都映射为表中的列. 在这种处理 ...

  9. 上海大智慧某站未授权访问&SQL注入

    详细说明: 注入:禁用JS,http://dzh.com.cn/admin/userlist.phphttp://dzh.com.cn/admin/editUser.php?username=test ...

  10. Android webview 点击超链接打开新的webview

    webview.setWebViewClient(new webViewClient() { HitTestResult hit = view.getHitTestResult(); if (hit ...