自制PHP框架之模型与数据库


Posted in PHP onMay 07, 2017

什么是模型?

我们的WEB系统一定会和各种数据打交道,实际开发过程中,往往一个类对应了关系数据库的一张或多张数据表,这里就会出现两个问题。

1.类和数据表,一方修改会导致另一方的修改,只要数据表结构不定下来,业务逻辑的开发几乎没法开工

2.获取数据时会牵涉很多SQL语句的拼接,如果数据结构变动,这些SQL需要改写

假如要开发一个博客系统,我们先设计两个Model和两张数据表

第一张数据表,表名是post,存储了博客文章,数据如下:

自制PHP框架之模型与数据库

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

自制PHP框架之模型与数据库

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 相关文章推荐
为php4加入动态flash文件的生成的支持
Oct 09 PHP
linux下 C语言对 php 扩展
Dec 14 PHP
PHP CKEditor 上传图片实现代码
Nov 06 PHP
ini_set的用法介绍
Jan 07 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
Feb 02 PHP
跟我学Laravel之安装Laravel
Oct 15 PHP
php提取字符串中网站url地址的方法
Dec 03 PHP
php递归遍历多维数组的方法
Apr 18 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
May 12 PHP
利用php输出不同的心形图案
Apr 22 PHP
thinkphp3.x中变量的获取和过滤方法详解
May 20 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
Dec 25 PHP
自制PHP框架之路由与控制器
May 07 #PHP
PHP-CGI远程代码执行漏洞分析与防范
May 07 #PHP
PHP关键特性之命名空间实例详解
May 06 #PHP
PHP 中使用explode()函数切割字符串为数组的示例
May 06 #PHP
Thinkphp 空操作、空控制器、命名空间(详解)
May 05 #PHP
thinkPHP实现的联动菜单功能详解
May 05 #PHP
thinkPHP实现的省市区三级联动功能示例
May 05 #PHP
You might like
Joomla下利用configuration.php存储简单数据
2010/05/19 PHP
PHP扩展程序实现守护进程
2015/04/16 PHP
thinkphp 抓取网站的内容并且保存到本地的实例详解
2017/08/25 PHP
Prototype使用指南之ajax
2007/01/10 Javascript
javascript中节点的最近的相关节点访问方法
2013/03/20 Javascript
JavaScript设计模式之抽象工厂模式介绍
2014/12/28 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
Bootstrap零基础入门教程(二)
2016/07/18 Javascript
js基本算法:冒泡排序,二分查找的简单实例
2016/10/08 Javascript
微信小程序三级联动地址选择器的实例代码
2017/07/12 Javascript
Vue cli+mui 区域滚动的实例代码
2018/01/25 Javascript
微信小程序WebSocket实现聊天对话功能
2018/07/06 Javascript
Vue表单之v-model绑定下拉列表功能
2019/05/14 Javascript
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
ES6中定义类和对象的方法示例
2019/07/31 Javascript
[02:39]DOTA2英雄基础教程 天怒法师
2013/11/29 DOTA
python enumerate函数的使用方法总结
2017/11/15 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
2018/02/18 Python
python实现抖音点赞功能
2019/04/07 Python
python飞机大战pygame碰撞检测实现方法分析
2019/12/17 Python
Python中sorted()排序与字母大小写的问题
2020/01/14 Python
jupyter notebook插入本地图片的实现
2020/04/13 Python
Python xlrd/xlwt 创建excel文件及常用操作
2020/09/24 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
python脚本定时发送邮件
2020/12/22 Python
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
大四自我鉴定
2014/02/08 职场文书
计算机通信专业推荐信
2014/02/22 职场文书
大型营销活动计划书
2014/04/28 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
车辆转让协议书
2014/09/24 职场文书
2014幼儿园家长工作总结
2014/11/10 职场文书
捐助倡议书
2015/01/19 职场文书
范文之农村基层党建工作报告
2019/10/24 职场文书
基于MySql验证的vsftpd虚拟用户
2021/11/07 MySQL
配置nginx负载均衡
2022/05/06 Servers