文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

    在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);


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯