自制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 相关文章推荐
使用VisualStudio开发php的图文设置方法
Aug 21 PHP
php将fileterms函数返回的结果变成可读的形式
Apr 21 PHP
PHP如何解决网站大流量与高并发的问题
Jun 25 PHP
PHP常用技术文之文件操作和目录操作总结
Sep 27 PHP
PHP统计目录大小的自定义函数分享
Nov 18 PHP
PHP中each与list用法分析
Jan 08 PHP
ThinkPHP3.2.3实现分页的方法详解
Jun 03 PHP
php使用SAE原生Mail类实现各种类型邮件发送的方法
Oct 10 PHP
PHP获取当前执行php文件名的代码
Mar 02 PHP
PHP中file_put_contents追加和换行的实现方法
Apr 01 PHP
PHP html_entity_decode()函数讲解
Feb 25 PHP
Laravel框架自定义分页样式操作示例
Jan 26 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
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
在PHP中使用灵巧的体系结构
2006/10/09 PHP
php中的观察者模式简单实例
2015/01/20 PHP
PHP执行系统命令函数实例讲解
2021/03/03 PHP
[IE&FireFox兼容]JS对select操作
2007/01/07 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
2012/02/02 Javascript
php与js的区别是什么
2013/08/05 Javascript
juery框架写的弹窗效果适合新手
2013/11/27 Javascript
js获取当前日期时间及其它日期操作汇总
2016/03/08 Javascript
JS随机打乱数组的方法小结
2016/06/22 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
2016/11/03 Javascript
基于Bootstrap 3 JQuery及RegExp的表单验证功能
2017/02/16 Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
2017/08/31 Javascript
webpack vue项目开发环境局域网访问方法
2018/03/20 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
2018/10/08 Javascript
JS使用cookie保存用户登录信息操作示例
2019/05/30 Javascript
Vue中的循环及修改差值表达式的方法
2019/08/29 Javascript
Vue中 axios delete请求参数操作
2020/08/25 Javascript
[40:55]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#4Newbee VS Fnatic
2016/03/03 DOTA
Python中列表(list)操作方法汇总
2014/08/18 Python
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
Python操作RabbitMQ服务器实现消息队列的路由功能
2016/06/29 Python
使用Python中的tkinter模块作图的方法
2017/02/07 Python
mac下pycharm设置python版本的图文教程
2018/06/13 Python
对python pandas 画移动平均线的方法详解
2018/11/28 Python
对python3新增的byte类型详解
2018/12/04 Python
CSS3实现滚动条动画效果代码分享
2016/08/03 HTML / CSS
凯特方迪化妆品官网:Kat Von D Beauty
2016/11/15 全球购物
Linux文件操作命令都有哪些
2015/02/27 面试题
毕业自我鉴定范文
2013/11/06 职场文书
毕业自我鉴定书
2014/03/24 职场文书
个人剖析材料范文
2014/09/30 职场文书
自荐信格式模板
2015/03/27 职场文书
中学音乐课教学反思
2016/02/18 职场文书
2019年聘任书的写作格式及范文!
2019/07/03 职场文书
python+pyhyper实现识别图片中的车牌号思路详解
2022/12/24 Python