溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP中面向對象的數(shù)據(jù)庫操作類

發(fā)布時間:2020-07-11 06:40:54 來源:網(wǎng)絡 閱讀:7122 作者:DemoHA 欄目:數(shù)據(jù)庫

    在PHP的面向過程中,我們可以通過封裝函數(shù)來實現(xiàn)對數(shù)據(jù)庫的操作,那么在面向過程中,我們同樣可以通過類來實現(xiàn)對數(shù)據(jù)庫的操作,整個過程和面向過程的思路大體差不多,但是代碼量更多了一些,實現(xiàn)起來稍微困難。一共實現(xiàn)了十個功能。先定義成員屬性,然后定義成員方法。一共分為連接數(shù)據(jù)庫的config文件、具體實現(xiàn)對數(shù)據(jù)庫操作的類文件、測試代碼。所有的代碼均是通過了測試,具體的測試結果由于篇幅問題沒有附圖。

具體實現(xiàn)功能:

1、連接數(shù)據(jù)庫;

2、插入數(shù)據(jù);

3、更新數(shù)據(jù);

4、刪除數(shù)據(jù);

5、修改數(shù)據(jù);

6、求最大值;

7、求最小值;

8、求平均數(shù);

9、求和;

10、指定查詢;


具體代碼分為三個部分:

一、config文件:主要用于連接數(shù)據(jù)庫

<?php
return array(
	'DB_HOST' => '127.0.0.1',   //主機
	'DB_USER' => 'root',		//用戶名	
	'DB_PWD' => '123456',		//密碼
	'DB_NAME' => 'blog',		//數(shù)據(jù)庫名
	'DB_CHARSET' => 'utf8',		//字符集
	'DB_PREFIX' => 'bbs_',		//前綴

);


二、數(shù)據(jù)庫操作類:

<?php
/**
 * 數(shù)據(jù)庫操作類
 */
class UserModel
{
	/*
	成員屬性
	 */
	//鏈接
	protected $link;
	//主機
	protected $host;
	//數(shù)據(jù)庫名字
	protected $dbName;
	//字符集
	protected $charset;
	//表名
	protected $table;
	//用戶名
	protected $user;
	//密碼
	protected $pwd;
	//表前綴
	protected $prefix;
	//字段
	protected $fields;
	//保存的查詢、更新、添加的參數(shù)
	protected $options;

	/*
	成員方法
	 */

	//初始化數(shù)據(jù)庫
	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('數(shù)據(jù)庫連接或者選擇數(shù)據(jù)庫失敗。');
		}

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

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



	}

	//連接數(shù)據(jù)庫成員方法
	protected function connect()
	{
		$conn = mysqli_connect($this->host,$this->user,$this->pwd);

		//連接數(shù)據(jù)庫失敗處理
		if (!$conn) {

			return flase;
		}

		//選擇數(shù)據(jù)失敗處理
		if (!mysqli_select_db($conn,$this->dbName)) {

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

		//返回處理結果
		return $conn;

	}
	//初始化表 【暫時出現(xiàn)報錯,后面用命名空間解決】
	protected function getTable()
	{
		//判斷用戶時候設置過?
		if (isset($this->table)) {

			//設置過就以用戶的為準,先把用戶前綴棄掉,然后拼接前綴,保證統(tǒng)一性
			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()
	{
		//如果有字段的文件說明以前緩存過這個文件,直接包含即可,但是需要知道文件路徑的規(guī)則
		//定義文件路徑
		$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);
		//執(zhí)行sql語句  需要定義成員方法query
		$data = $this->query($sql);

		$fields = [];
		//想要獲取字段,需要對返回的數(shù)據(jù)進行遍歷
		foreach ($data as $key => $value) {
			$fields[] = $value['Field'];
			if ($value['Key'] == 'PRI') {
				$fields['_pk'] = $value['Field'];
			}
		}
		return $fields;


	}

	//系統(tǒng)級查詢(定義為 public ),在外部調用的時候,想自定義SQL語句可以只是調用該成員方法
	//查詢相應的結果,這個僅供讀取使用查詢相應的結果
	public function query($sql)
	{
		//執(zhí)行一條SQL語句
		$result = mysqli_query($this->link,$sql);

		if ($result) {
			$data = [];
			//獲取每行數(shù)據(jù)
			while ($row = mysqli_fetch_assoc($result)) {
				$data[] = $row;
			}
			return $data;

		} else {
			return false;
		}


	}

	//查詢成員方法
	//準備好無需換的SQL語句
	//用戶調用詢的時候,將call里面保存進去的參數(shù),一一替換sql語句
	//發(fā)送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']);

		//判斷字段是什么形式(字符串、數(shù)組)
		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])){
			//如果是字符串就先變?yōu)閿?shù)組進行處理
			$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])) {

				//用戶傳進來的是一個整 數(shù),就是查詢指定的條數(shù)
				return 'LIMIT ' . $this->options['limit'][0];

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

				//用戶傳進來的是一個數(shù)組,則數(shù)組中的第一個元素為$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并執(zhí)行
		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));
	}

	//處理插入時候的值
	//分為字符串  數(shù)組 空的情況處理
	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 返回受影響的行數(shù)

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

	//求總數(shù)
	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'];
	}
	//求最大數(shù)
	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'];
	}
	//求最小數(shù)
	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'];
	}
	//求平均數(shù)
	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'];
		//把傳入的統(tǒng)一轉化為小寫
		$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');

//測試求最大數(shù)
echo $blog->max('uid');

//測試求最小數(shù)
echo $blog->min();

//測試求平均數(shù)
echo $blog->avg();

//測試自動的一個按照字段來查詢
$data = $blog->getByPassword('123456');
var_dump($data);


向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI