自制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 相关文章推荐
php print EOF实现方法
May 21 PHP
PHP 将图片按创建时间进行分类存储的实现代码
Jan 05 PHP
php编写一个简单的路由类
Apr 13 PHP
php继承的一个应用
Sep 06 PHP
解析php中两种缩放图片的函数,为图片添加水印
Jun 14 PHP
zend framework框架中url大小写问题解决方法
Aug 19 PHP
基于linnux+phantomjs实现生成图片格式的网页快照
Apr 15 PHP
php生成4位数字验证码的实现代码
Nov 23 PHP
手把手编写PHP框架 深入了解MVC运行流程
Sep 19 PHP
基于CI框架的微信网页授权库示例
Nov 25 PHP
PHP实现大数(浮点数)取余的方法
Feb 18 PHP
ThinkPHP框架实现数据增删改
May 07 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
json的键名为数字时的调用方式(示例代码)
2013/11/15 PHP
3种php生成唯一id的方法
2015/11/23 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
Laravel路由设定和子路由设定实例分析
2016/03/30 PHP
PHP数组操作实例分析【添加,删除,计算,反转,排序,查找等】
2016/12/24 PHP
PHP中PDO事务处理操作示例
2018/05/02 PHP
redis+php实现微博(一)注册与登录功能详解
2019/09/23 PHP
javascript获取当前日期时间及其它操作函数
2011/01/11 Javascript
Mac/Windows下如何安装Node.js
2013/11/22 Javascript
js实现按一下删除键删除整个单词附demo
2014/09/05 Javascript
简介JavaScript中用于处理正切的Math.tan()方法
2015/06/15 Javascript
jquery中键盘事件小结
2016/02/24 Javascript
原生js获取元素样式的简单方法
2016/08/06 Javascript
解决淘宝cnpm 安装后cnpm不是内部或外部命令的问题
2018/05/17 Javascript
vue cli3.0 引入eslint 结合vscode使用
2019/05/27 Javascript
通过layer实现可输入的模态框的例子
2019/09/27 Javascript
vue循环中点击选中再点击取消(单选)的实现
2020/09/10 Javascript
swiper实现导航滚动效果
2020/12/13 Javascript
Webpack3+React16代码分割的实现
2021/03/03 Javascript
[29:16]完美世界DOTA2联赛决赛日 Inki vs LBZS 第三场 11.08
2020/11/10 DOTA
python中的__init__ 、__new__、__call__小结
2014/04/25 Python
Python入门篇之条件、循环
2014/10/17 Python
在Python中操作文件之seek()方法的使用教程
2015/05/24 Python
Flask的图形化管理界面搭建框架Flask-Admin的使用教程
2016/06/13 Python
Python 实现随机数详解及实例代码
2017/04/15 Python
Python 操作MySQL详解及实例
2017/04/30 Python
Django框架模板语言实例小结【变量,标签,过滤器,继承,html转义】
2019/05/23 Python
Python Pandas 获取列匹配特定值的行的索引问题
2019/07/01 Python
Python3 批量扫描端口的例子
2019/07/25 Python
旅游管理专业学生求职信
2013/09/28 职场文书
2014年学习雷锋活动总结
2014/03/01 职场文书
销售人员求职的自我评价分享
2014/03/15 职场文书
大学生励志演讲稿
2014/04/25 职场文书
2016年法制宣传月活动总结
2016/04/01 职场文书
感谢信
2019/04/11 职场文书
你有一份《诚信考试承诺书》待领取
2019/11/13 职场文书