「七天自制PHP框架」第二天:模型与数据库
往期回顾:「七天自制PHP框架」第一天:路由与控制器,点击此处
什么是模型?
我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题。
1.类和数据表,一方修改会导致另一方的修改,只要数据表结构不定下来,业务逻辑的开发几乎没法开工
2.获取数据时会牵涉很多SQL语句的拼接,如果数据结构变动,这些SQL需要改写
假如要开发一个博客系统,我们先设计两个Model和两张数据表
第一张数据表,表名是post,存储了博客文章,数据如下:

第二章数据表,表名是comment,存储了博客文章的评论,数据如下:

post和comment是一对多的关系,每一篇博客文章对应了多条评论,每一条评论只属于一篇文章。
Model类的设计之前,我们先定义好三个接口
interface IModel{
public static function all();
public static function get($id);
public static function where($condition,$value);
}
定义Model类
class Model implements IModel{
public static $table;
public static $db;
public function __construct(){
self::$db=new MySQL();
}
public static function get($id){
return self::where('id',$id);
}
public static function where($condition,$value){
$sql=sprintf("select * from %s where %s='%s'",self::$table,$condition,$value);
return self::$db->Query($sql);
}
public static function all(){
$sql=sprintf("select * from %s",self::$table);
return self::$db->Query($sql);
}
}
这三个接口分别负责了三种查询:遍历查询,条件查询,按编号查询,其实这三种接口的设计并不是最科学的,甚至get方法不过是where的一种特殊形式,但是这样的设计并不影响我们工程,甚至也有助于理解,我们后期会对这段代码做改动。
之所以在Model类里就完成了SQL的拼接,就是希望在子类中不必重复再写SQL。
然后是Post类的定义
class PostModel extends Model{
public $postid;
public function __construct(){
parent::__construct();
parent::$table='post';
}
}
还有Comment类的定义
class CommentModel extends Model{
public $commentid;
public function __construct(){
parent::__construct();
parent::$table='comment';
}
}
我们可以在控制器的方法中写这样的代码来完成调用数据
$post=new PostModel();
$post::all();
$arr=$post::get('1');
var_dump($arr); $comment=new CommentModel();
$arr=$comment::get('2');
var_dump($arr);
我们发现,这样的代码很简洁,但是问题也随之而来,我们SQL查询时候,还有很多复杂的联表查询如join操作,如此,拼接SQL还是不可避免的,这个复杂的问题,我们放在后面解决。
模型与数据库
先写一个DB抽象类,规定类需要实现的方法
abstract class DB{
private $IP;
private $user;
private $pwd;
private $name;
private $connection;
abstract public function Execute($sql);
abstract public function Query($sql);
}
这里以MySQL数据为例,当然你也完全可以实现一套Sqlite数据库的接口。
class MySQL extends DB{
public function MySQL(){
/*Config*/
$this->IP='*';
$this->ServerID='*';
$this->ServerPassword='*';
$this->DataBaseName='*';
/*End of Config*/
$this->connection=mysqli_connect($this->IP,$this->ServerID,$this->ServerPassword,$this->DataBaseName);
if(!$this->connection){
die('Could not connect'.$this->connection);
}
mysqli_query($this->connection,'set names utf8');
}
public function Execute($sql){
return mysqli_query($this->connection,$sql);
}
public function Query($sql){
$result=mysqli_query($this->connection,$sql);
$arr=array();
while($row=mysqli_fetch_array($result)){
$arr[]=$row;
}
return $arr;
}
public function Close(){
mysqli_close($this->connection);
}
}
谈到数据库类,上述的写法仍不是最好的,因为我们可以使用单例模式来保证DB类只有一次初始化,来节省硬件资源的开销,但这不是本节的主题,我们把设计模式放在之后来谈。
「七天自制PHP框架」第二天:模型与数据库的更多相关文章
- 「七天自制PHP框架」第三天:PHP实现的设计模式
往期回顾:「七天自制PHP框架」第二天:模型与数据库,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 为什么要使用设计模 ...
- 「七天自制PHP框架」第四天:模型关联
往期回顾:「七天自制PHP框架」第三天:PHP实现的设计模式,点击此处 原文地址:http://www.cnblogs.com/sweng/p/6624845.html,欢迎关注:编程老头 前阵子在网 ...
- 「七天自制PHP框架」应用:JSON生成器
刚刚开始学做一个WebAPP,数据查询的一般套路是通过一张PHP页面读取数据库,获得列表后“嵌写”在PHP页面中,虽然写法上丑陋至极,但也有“快糙猛”出效果的成就感,如图. 后来想想,不对啊,难道以后 ...
- 「七天自制PHP框架」第一天:路由与控制器
我们为什么要使用路由? 原因1:一个更漂亮的URI 1.URI的改进 刚刚开始学PHP时,我们一定写过blog.php?id=1之类的URI,使用GET方式获取参数.这样的URI有两个缺点,一是容易被 ...
- 「七天自制PHP框架」应用:Model外键链接
这里以行政区数据为例: 一级行政区数据范例: 二级行政区范例: 三级行政区范例: 在Model层建立三个Model class ProvinceModel extends Model{ public ...
- 「7天自制PHP框架」第一天:路由与控制器
我们为什么要使用路由? 原因1:一个更漂亮的URI 1.URI的改进 刚刚开始学PHP时,我们一定写过blog.php?id=1之类的URI,使用GET方式获取参数.这样的URI有两个缺点,一是容易被 ...
- 「BUAA OO Unit 2 HW8」第二单元总结
「BUAA OO Unit 2 HW8」第二单元总结 目录 「BUAA OO Unit 2 HW8」第二单元总结 Part 0 前言 Part 1 第五次作业 1.1 作业要求 1.2 架构设计 1. ...
- Web自动化必会知识:「Web基础、元素定位、元素操作、Selenium运行原理、项目实战+框架」
1.web 基础-html.dom 对象.js 基本语法 Dom 对象里面涉及元素定位以及对元素的修改.因为对元素操作当中涉及的一些 js 操作,js 基本语法要会用.得要掌握前端的基本用法.为什么要 ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
随机推荐
- Knockoutjs : Unable to process binding "value:
刚刚自学knockoutjs,老是碰到稀奇古怪的问题. 在自学knockout.js的时候经常遇到 Unable to process binding "value:的问题.目前总结了以下几 ...
- 记一次企业级爬虫系统升级改造(六):基于Redis实现免费的IP代理池
前言: 首先表示抱歉,春节后一直较忙,未及时更新该系列文章. 近期,由于监控的站源越来越多,就偶有站源做了反爬机制,造成我们的SupportYun系统小爬虫服务时常被封IP,不能进行数据采集. 这时候 ...
- php基本数据类型需要注意的地方
一.布尔(Boolean) 手册中提到特殊类型NULL(包括尚未赋值的变量)会被换为false值,我自己在测试的时候发现NULL值可以转换为false,虽然false也会输出,但是尚未赋值的变量会报N ...
- iOS 如何保持线程一直在运转(二)
一.接着上一篇通过NSThread可以方便的创建一个线程,并且启动线程的Runloop,在线程体中执行一个while循环 然后我们就可以方便得利用这个线程了 - (void)threadRun:(NS ...
- .net core版 文件上传/ 支持批量上传,拖拽以及预览,bootstrap fileinput上传文件
asp.net mvc请移步 mvc文件上传支持批量上传,拖拽以及预览,文件内容校验 本篇内容主要解决.net core中文件上传的问题 开发环境:ubuntu+vscode 1.导入所需要的包:n ...
- bootstrap-dialog插件的使用
官网文档:http://nakupanda.github.io/bootstrap3-dialog BootstrapDialog.show({ message: 'Hi Apple!', messa ...
- PMP和PRINCE2应该选择哪个?光环国际项目管理认证
对于项目管理课程的选择,我们不能盲目地做选择,一定要从自身实际出发.从来都没有更好的课程,只有更合适自己的课程. 那么,如何选择合适自己的项目管理课程呢? 让我们从PMP与PRINCE2之间的差异开始 ...
- PMBOK 和 PRINCE2的技术不同的地方是什么
首先,PMBOK是一个框架指导,PRINCE2是一种实现方法. PMBOK是一种建议及最佳实践的集锦.PMBOK包含项目管理的工具和技术并且是一个指导,告诉我们如何做事情,在一种环境中怎样处理问题;而 ...
- Unity 3D Framework Designing(9)——构建统一的 Repository
谈到 『Repository』 仓储模式,第一映像就是封装了对数据的访问和持久化.Repository 模式的理念核心是定义了一个规范,即接口『Interface』,在这个规范里面定义了访问以及持久化 ...
- linux redis安装
redis官网地址:http://www.redis.io/ 在Linux下安装Redis非常简单,具体步骤如下(官网有说明): 1.下载源码,解压缩后编译源码. $ wget http://down ...