自制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 相关文章推荐
回答PHPCHINA上的几个问题:URL映射
Feb 14 PHP
php 传值赋值与引用赋值的区别
Dec 29 PHP
PHP合并两个数组的两种方式的异同
Sep 14 PHP
关于Iframe如何跨域访问Cookie和Session的解决方法
Apr 15 PHP
php object转数组示例
Jan 15 PHP
php switch语句多个值匹配同一代码块的实现
Mar 03 PHP
Win7下手动安装apache2.2、php5.4笔记
Apr 03 PHP
php实现生成验证码实例分享
Apr 10 PHP
ThinkPHP表单令牌错误的相关解决方法分析
May 20 PHP
PHP开发制作一个简单的活动日程表Calendar
Jun 20 PHP
PHP序列化的四种实现方法与横向对比
Nov 29 PHP
详细分析PHP 命名空间(namespace)
Jun 30 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
php 小乘法表实现代码
2009/07/16 PHP
php echo()和print()、require()和include()函数区别说明
2010/03/27 PHP
php文档更新介绍
2011/07/22 PHP
基于empty函数的判断详解
2013/06/17 PHP
PHP汉字转换拼音的函数代码
2015/12/30 PHP
PHP Imagick完美实现图片裁切、生成缩略图、添加水印
2016/02/22 PHP
PHP实现的简单适配器模式示例
2017/06/22 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
Javascript操纵Cookie实现购物车程序
2006/11/23 Javascript
JS中的log对象获取以及debug的写法介绍
2014/03/03 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
jQuery取得iframe中元素的常用方法详解
2016/01/14 Javascript
Javascript实现代码折叠功能
2016/08/25 Javascript
Javascript json object 与string 相互转换的简单实现
2016/09/27 Javascript
Angular2 Service实现简单音乐播放器服务
2017/02/24 Javascript
AngularJS通过ng-Img-Crop实现头像截取的示例
2017/08/17 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
学习node.js 断言的使用详解
2019/03/18 Javascript
JS实现骰子3D旋转效果
2019/10/24 Javascript
python实现定时播放mp3
2015/03/29 Python
Pycharm 创建 Django admin 用户名和密码的实例
2018/05/30 Python
python随机数分布random均匀分布实例
2019/11/27 Python
Python爬取某平台短视频的方法
2021/02/08 Python
html5本地存储_动力节点Java学院整理
2017/07/12 HTML / CSS
全球速卖通巴西站点:Aliexpress巴西
2016/08/24 全球购物
阿拉伯世界最大的电子商务网站:Souq沙特阿拉伯
2016/10/28 全球购物
阿里云:Aliyun.com
2017/02/15 全球购物
草莓网化妆品澳大利亚站:Strawberrynet AU
2017/12/18 全球购物
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
意大利消费电子产品购物网站:SLG Store
2019/12/26 全球购物
英国排名第一的宠物店:PetPlanet
2020/02/02 全球购物
小学门卫岗位职责
2013/12/17 职场文书
商务日语专业的自荐信
2014/05/23 职场文书
模特大赛策划方案
2014/05/28 职场文书
四风专项整治工作情况汇报
2014/10/28 职场文书
Python如何快速找到多个字典中的公共键(key)
2022/04/29 Python