您好,登錄后才能下訂單哦!
在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);
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。