PHP中面向对象的数据库操作类

发布时间:2020-07-11 06:40:54 作者:DemoHA
来源:网络 阅读:7125

    在PHP的面向过程中,我们可以通过封装函数来实现对数据库的操作,那么在面向过程中,我们同样可以通过类来实现对数据库的操作,整个过程和面向过程的思路大体差不多,但是代码量更多了一些,实现起来稍微困难。一共实现了十个功能。先定义成员属性,然后定义成员方法。一共分为连接数据库的config文件、具体实现对数据库操作的类文件、测试代码。所有的代码均是通过了测试,具体的测试结果由于篇幅问题没有附图。

具体实现功能:

1、连接数据库;

2、插入数据;

3、更新数据;

4、删除数据;

5、修改数据;

6、求最大值;

7、求最小值;

8、求平均数;

9、求和;

10、指定查询;


具体代码分为三个部分:

一、config文件:主要用于连接数据库

<?php
return array(
	'DB_HOST' => '127.0.0.1',   //主机
	'DB_USER' => 'root',		//用户名	
	'DB_PWD' => '123456',		//密码
	'DB_NAME' => 'blog',		//数据库名
	'DB_CHARSET' => 'utf8',		//字符集
	'DB_PREFIX' => 'bbs_',		//前缀

);


二、数据库操作类:

<?php
/**
 * 数据库操作类
 */
class UserModel
{
	/*
	成员属性
	 */
	//链接
	protected $link;
	//主机
	protected $host;
	//数据库名字
	protected $dbName;
	//字符集
	protected $charset;
	//表名
	protected $table;
	//用户名
	protected $user;
	//密码
	protected $pwd;
	//表前缀
	protected $prefix;
	//字段
	protected $fields;
	//保存的查询、更新、添加的参数
	protected $options;

	/*
	成员方法
	 */

	//初始化数据库
	public function __construct(Array $config)
	{
		//把一批成员属性都初始化
		$this->host = $config['DB_HOST'];
		$this->user = $config['DB_USER'];
		$this->pwd = $config['DB_PWD'];
		$this->dbName = $config['DB_NAME'];
		$this->charset = $config['DB_CHARSET'];
		$this->prefix = $config['DB_PREFIX'];
		//连接
		$this->link = $this->connect();
		//判断连接成功与否  失败处理
		if (!$this->link) {
			exit('数据库连接或者选择数据库失败。');
		}

		//表名  需要处理
		$this->table = $this->getTable();

		//字段 	需要处理
		$this->fields = $this->getFields();



	}

	//连接数据库成员方法
	protected function connect()
	{
		$conn = mysqli_connect($this->host,$this->user,$this->pwd);

		//连接数据库失败处理
		if (!$conn) {

			return flase;
		}

		//选择数据失败处理
		if (!mysqli_select_db($conn,$this->dbName)) {

			return false ;
		}
		//设置字符集
		mysqli_set_charset($conn,$this->charset);

		//返回处理结果
		return $conn;

	}
	//初始化表 【暂时出现报错,后面用命名空间解决】
	protected function getTable()
	{
		//判断用户时候设置过?
		if (isset($this->table)) {

			//设置过就以用户的为准,先把用户前缀弃掉,然后拼接前缀,保证统一性
			return $this->prefix . ltrim($this->table,$this->prefix);
		} else {

			//没有设置过就用 类名拼接前缀,组成一个全新的的表名
			//get_class() 获取类名 等同于 __CLASS__
			//获取类名后进行字串提取[substr( string,start,length )],并且全部转换为小写[strtolower()]
			return $this->prefix . strtolower(substr(get_class($this),0,-5));
		}
	}
	//初始化字段 需要把字段缓存到一个文件里面去
	protected function getFields()
	{
		//如果有字段的文件说明以前缓存过这个文件,直接包含即可,但是需要知道文件路径的规则
		//定义文件路径
		$filePath = './caceh/' . $this->table . '.php';

		//判断时候有缓存文件
		if (file_exists($filePath)) {

			//存在缓存文件直接包含即可
			return include $filePath;
		} else {

			//没有的话就需要生成一个缓存文件
			//首先需要查询字段
			$fields = $this->queryFields();

			//var_export() 输出或返回一个变量的字符串  true表示不打印  将其保存下来
			$str = "<?php \n return ". var_export($fields,true) . ';?>';
			//写入到缓存文件file_put_contents(文件保存路径,需要写进去的内容)
			file_put_contents($filePath, $str);

		}
		return $fields;


	}

	//查询字段处理
	protected function queryFields()
	{
		//打印字段的sql语句
		$sql = 'desc ' . $this->table;
		//var_dump($sql);
		//执行sql语句  需要定义成员方法query
		$data = $this->query($sql);

		$fields = [];
		//想要获取字段,需要对返回的数据进行遍历
		foreach ($data as $key => $value) {
			$fields[] = $value['Field'];
			if ($value['Key'] == 'PRI') {
				$fields['_pk'] = $value['Field'];
			}
		}
		return $fields;


	}

	//系统级查询(定义为 public ),在外部调用的时候,想自定义SQL语句可以只是调用该成员方法
	//查询相应的结果,这个仅供读取使用查询相应的结果
	public function query($sql)
	{
		//执行一条SQL语句
		$result = mysqli_query($this->link,$sql);

		if ($result) {
			$data = [];
			//获取每行数据
			while ($row = mysqli_fetch_assoc($result)) {
				$data[] = $row;
			}
			return $data;

		} else {
			return false;
		}


	}

	//查询成员方法
	//准备好无需换的SQL语句
	//用户调用询的时候,将call里面保存进去的参数,一一替换sql语句
	//发送SQL语句
	//返回查询的结果
	public function select()
	{
		//拼接sql语句
		$sql = "select %FIELDS% from %TABLE% %WHERE% %GROUP% %HAVING% %ORDER% %LIMIT%";

		//将sql语句中的相应部分替换
		$newsql = str_replace(
					array(
						'%FIELDS%',
						'%TABLE%',
						'%WHERE%',
						'%GROUP%',
						'%HAVING%',
						'%ORDER%',
						'%LIMIT%',
					),
					array(
						$this->parseFields(),
						$this->parseTable(),
						$this->parseWhere(),
						$this->parseGroup(),
						$this->parseHaving(),
						$this->parseOrder(),
						$this->parseLimit(),
					),
					$sql
				);
		echo $newsql;
		$this->sql = $newsql;
		return $this->query($newsql);
	}
	//字段处理
	protected function parseFields()
	{
		//因为我们对比字段的时不需要对比主键是谁,所以需要unset()
		//将当前的字段赋值给一个变量
		$fields = $this->fields;

		unset($fields['_pk']);

		//判断字段是什么形式(字符串、数组)
		if (is_array($this->options['fields'][0])) {

			//遍历取出键值
			foreach ($this->options['fields'][0] as $key => $value) {
				//判断传入的字段时候合法(属于表结构中的字段)
				if (!in_array($value, $fields)) {
					//如果不属于合法的字段就unset()
					unset($this->options['fields'][0][$key]);
				}
			}
			return join(',',$this->options['fields'][0]);

		} else if (is_string($this->options['fields'][0])){
			//如果是字符串就先变为数组进行处理
			$this->options['fields'][0] = explode(',', $this->options['fields'][0]);
			//遍历
			foreach ($this->options['fields'][0]  as $key => $value) {
				//判断字段是否合法
				if (!in_array($value,$fields)) {

					unset($this->options['fields'][0][$key]);
				}
				return join(',',$this->options['fields'][0]);
			}

		} else {
			return join(',',$fields);
		}

	}

	//判断用户有没有手动指定过查询哪个用
	//如果指定过,则以用户设定的options里面的表为准
	//如果没有设定过,则以默认的为准
	protected function parseTable()
	{
		if (isset($this->options['table'][0])) {
			return $this->options['table'][0];
		} else {
			return $this->table;
		}

	}


	//判断用户设置过where 如果设置过就以用户设置为准,没有设置就为空

	protected function parseWhere()
	{
		if (isset($this->options['where'][0])) {
			return 'WHERE ' .$this->options['where'][0];
		} else {
			return '';
		}
	}


	//判断用户设置过group 如果设置过就以用户设置为准,没有设置就为空

	protected function parseGroup()
	{
		if (isset($this->options['where'][0])) {
			return 'GROUP BY ' .$this->options['group'][0];
		} else {
			return '';
		}
	}

	//判断用户设置过having如果设置过就以用户设置为准,没有设置就为空

	protected function parseHaving()
	{
		if (isset($this->options['having'][0])) {
			return 'HAVING ' .$this->options['having'][0];
		} else {
			return '';
		}
	}

	//判断用户设置过order如果设置过就以用户设置为准,没有设置就为空
	protected function parseOrder()
	{
		if (isset($this->options['order'][0])) {
			return 'ORDER BY ' .$this->options['order'][0];
		} else {
			return '';
		}
	}

	//limit可以有以下几种传法


	protected function parseLimit()
	{
		if (isset($this->options['limit'][0])) {

			if (is_int($this->options['limit'][0])) {

				//用户传进来的是一个整 数,就是查询指定的条数
				return 'LIMIT ' . $this->options['limit'][0];

			} else if (is_array($this->options['limit'][0])){

				//用户传进来的是一个数组,则数组中的第一个元素为$offset,第二个元素为$num
				return 'LIMIT ' . join(',',$this->options['limit'][0]);
			} else {

				//如果户传进来的是一个字符串,则以用户传的为准
				return 'LIMIT ' . $this->options['limit'][0];
			}
		} else {

			return '';
		}
	}

	//插入的成员方法
	public function insert($data)
	{
		//SQL语句
		$sql = "insert into %TABLE%(%FIELDS%) values(%VALUES%) ";
		//替换
		$newsql = str_replace(
						array(
							'%TABLE%',
							'%FIELDS%',
							'%VALUES%'
						),
						array(
							$this->parseTable(),
							$this->parseInsertFieldes($data),
							join (',',$this->parseValue($data)),
						),
						$sql
					);
		//重新赋值
		$this->sql = $newsql;
		echo $this->sql;
		//调用exec并执行
		return $this->exec($newsql,true);

	}
	//处理插入时候的字段
	protected function parseInsertFieldes(&$data)
	{
		foreach ($data as $key => $value) {
			if (!in_array($key,$this->fields)) {
				unset($data[$key]);
			}
		}
		return join(',',array_keys($data));
	}

	//处理插入时候的值
	//分为字符串  数组 空的情况处理
	protected function parseValue($data)
	{

		if (is_string($data)) {
			$data = '\'' . $data . '\'';
		} else if (is_array($data)){
			$data = array_map(array($this, 'parseValue'),$data);
		} else if (is_null($data)){
			$data = 'null';
		}

		return $data;
	}
	//
	public function exec($sql,$isInsertId = false)
	{
		$result = mysqli_query($this->link,$sql);

		if ($result) {

			if ($isInsertId) {
				//insertfan返回自动增长的id
				return mysqli_insert_id($this->link);
			} else {
				//update delete 返回受影响的行数

				return mysqli_affected_rows($this->link);
			}
		} else {
			return false;
		}
	}

	//更新方法
	public function update($data)
	{
		$sql = "update %TABLE% set %SETS% %WHERE% %ORDER% %LIMIT%";

		$newsql = str_replace(
					array(
						'%TABLE%',
						'%SETS%',
						'%WHERE%',
						'%ORDER%',
						'%LIMIT%'
					),
					array(
						$this->parseTable(),
						$this->parseSets($data),
						$this->parseWhere(),
						$this->parseOrder(),
						$this->parseLimit(),
					),
					$sql
				);
		$this->sql = $newsql;
		//echo $newsql;
		return $this->exec($newsql);

	}

	//更新内容设置
	protected function parseSets($data)
	{
		$sets = [];
		foreach ($data as $key => $value) {
			 if (in_array($key,$this->fields)) {
			 	$sets[] = $key . '=' . $this->parseValue($value);
			 }
		}
		return join(',',$sets);
	}


	//删除方法
	public function delete()
	{
		$sql = "delete from %TABLE% %WHERE% %ORDER% %LIMIT%";

		$newsql = str_replace(
					array(
						'%TABLE%',
						'%WHERE%',
						'%ORDER%',
						'%LIMIT%'
					),
					array(
						$this->parseTable(),
						$this->parseWhere(),
						$this->parseOrder(),
						$this->parseLimit(),
					),
					$sql
				);

		$this->sql = $newsql;

		return $this->exec($newsql);
	}

	//求总数
	public function sum($field = null )
	{
		if (is_null($field)) {
			$field = $this->fields['_pk'];
		}

		$sql = "select count($field) as sum from %TABLE% %WHERE% ";

		$newsql = str_replace(
						array(
							'%TABLE%',
							'%WHERE%',
						),
						array(
							$this->parseTable(),
							$this->parseWhere(),
							),
						$sql
				);
		$this->sql = $newsql;
		$data = $this->query($newsql);
		return $data[0]['sum'];
	}
	//求最大数
	public function max($field = null )
	{
		if (is_null($field)) {
			$field = $this->fields['_pk'];
		}

		$sql = "select max($field) as max from %TABLE% %WHERE% ";

		$newsql = str_replace(
					array(
						'%TABLE%',
						'%WHERE%',
					),
					array(
						$this->parseTable(),
						$this->parseWhere(),
					),
					$sql
				);
		$this->sql = $newsql;
		$data = $this->query($newsql);
		return $data[0]['max'];
	}
	//求最小数
	public function min($field = null )
	{
		if (is_null($field)) {
			$field = $this->fields['_pk'];
		}

		$sql = "select min($field) as min from %TABLE% %WHERE% ";

		$newsql = str_replace(
					array(
						'%TABLE%',
						'%WHERE%',
					),
					array(
						$this->parseTable(),
						$this->parseWhere(),
					),
					$sql
				);
		$this->sql = $newsql;
		$data = $this->query($newsql);
		return $data[0]['min'];
	}
	//求平均数
	public function avg($field = null )
	{
		if (is_null($field)) {
			$field = $this->fields['_pk'];
		}

		$sql = "select avg($field) as avg from %TABLE% %WHERE% ";

		$newsql = str_replace(
					array(
						'%TABLE%',
						'%WHERE%',
					),
					array(
						$this->parseTable(),
						$this->parseWhere(),
					),
					$sql
				);
		$this->sql = $newsql;
		$data = $this->query($newsql);
		return $data[0]['avg'];
	}


	//自动的一个按照字段来查询的智能化查询方法
	protected function getBy($field,$value)
	{
		$sql = "select %FIELDS% from %TABLE% %WHERE%";

		$newsql = str_replace(
					array(
						'%FIELDS%',
						'%TABLE%',
						'%WHERE%'
					),
					array(
						$this->parseFields(),
						$this->parseTable(),
						' WHERE '.$field . "='$value'",
					),
					$sql
				);
		$this->sql = $newsql;
		echo $newsql;
		return $this->query($newsql);
	}

	//__call方法,针对用户请求limit(), order(),group()等将其保存到options中, 判断其方法合法性;
	//并且return $this 让其能够连贯操作,
	public function __call($func,$args)
	{
		//合法的
		$allow = ['where','table','fields','order','limit','group','having'];
		//把传入的统一转化为小写
		$func = strtolower($func);
		if (in_array($func,$allow)) {
			$this->options[$func] = $args;
			return $this;
		} else if(substr($func,0,5) == 'getby'){
			$field = substr($func,5);

			if (in_array($field,$this->fields)) {
				return $this->getBy($field,$args[0]);
			}
		} else {
			exit ('方法不合法!');
		}

	}

	//析構方法 關閉頁面/對象消費時候調用
	public function __destruct()
	{
		mysqli_close($this->link);
	}
}



三、测试(验证)代码:

//包含文件
$config = include 'config.php';

$blog = new UserModel($config);
//测试查询

$data = $blog->fields('uid,uesrname,password')->table('bbs_user')->limit([1,2])->order('uid desc ')->group('username')->select();

var_dump($data);

//插入测试
$_POST['uesrname'] = 'chen';
$_POST['password'] = 123456;
$_POST['creatime'] = 123423;

$_POST['senlin'] = '不存在的字段处理';

echo $blog->insert($_POST);

//更新测试

$_POST['uesrname'] = '1kkkkk12';
$_POST['password'] = 123456;
$_POST['createtime'] = 234567;
$_POST['haiyan'] = '你可长点心眼吧';
echo $blog->where('uid>0')->limit('1')->update($_POST);

//删除测试
echo $blog->where('uid>0 and uid<2')->delete();

//测试求和
echo $blog->sum('uid');

//测试求最大数
echo $blog->max('uid');

//测试求最小数
echo $blog->min();

//测试求平均數
echo $blog->avg();

//测试自动的一个按照字段来查询
$data = $blog->getByPassword('123456');
var_dump($data);


推荐阅读:
  1. PHP中面向对象中的模板引擎类
  2. PHP中面向对象的图片处理类

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

数据库 操作 面向对象

上一篇:oracle 数据库dmp文件导入导出

下一篇:shell   if 详解

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》