1. 程式人生 > >PHP基礎之與MySQL那些事

PHP基礎之與MySQL那些事

#前言 這篇文章會對PHP的MySQL擴充套件庫,MySQLI的擴充套件庫,SQL批量執行,事務控制等等進行一些簡單的講解。 #MySQL擴充套件 PHP中MySQL擴充套件,雖然因為安全的原因,在PHP5.6及往上不在支援MySQL擴充套件庫,但是還是要學習的,通過編寫案例的方式來講解。 ##案例 先說下操作資料庫的大體思路吧,就是先獲取連線-》選擇資料庫-》設定操作編碼-》傳送sql指令-》對返回的結果進行處理-》釋放資源,斷開連線。案例是一個線上詞典查詢。下面是建立表的sql語句: ``` create database worddb create table words( id int primary key auto_increment, enword varchar(32) not null, chword varchar(256) not null ); insert into words(enword,chword) values ('boy','男孩') insert into words(enword,chword) values ('school','學校') ``` 因為是練習,所以就插入了兩條資料。接下來就是編寫SQL工具類,程式碼如下: ``` conn=mysql_connect($this->host,$this->user,$this->password); if (!$this->conn){ die("連線資料庫失敗!".mysql_error()); } mysql_select_db($this->db,$this->conn); mysql_query("set names utf8"); } //完成select function execute_dql($sql){ $res=mysql_query($sql) or die(mysql_error()); return $res; } //完成insert,update,delete function execute_dml($sql){ $b=mysql_query($sql,$this->
conn); if (!$b){ return 0; }else{ //因為有些情況執行成功,但沒有行數影響,所以在判斷一下。 if (mysql_affected_rows($this->conn)>0){ return 1; }else{ return 2; } } } } ?> ``` 之後就是前端頁面的編寫了,程式碼如下,有點醜: ``` 線上詞典

字典

查詢英文

請輸入英文:

查詢中文

請輸入中文: ``` 接下來就是後端邏輯程式碼了,如下: ``` "; echo "回到主頁面"; } if ($type=="search1") { if (isset($_POST[yingyu])) { $en_word = $_POST[yingyu]; } else { echo "請輸入"; echo "回到主頁面"; } $sql = "select chword from words where enword='" . $en_word . "' limit 0,1"; //查詢,呼叫sql工具類 $SqlTool = new SqlTool(); $res = $SqlTool->execute_dql($sql); if ($row = mysql_fetch_assoc($res)) { echo $en_word . "對應的中文為" . $row['chword']; } else { echo "查詢沒有這個詞條.
"; echo "回到主頁面"; } //釋放資源 mysql_free_result($res); }else if($type == "search2") { if (isset($_POST[hanyu])) { $ch_word = $_POST[hanyu]; } else { echo "請輸入"; echo "回到主頁面"; } $sql = "select enword from words where chword like '%" . $ch_word . "%'"; //查詢,呼叫sql工具類 $SqlTool = new SqlTool(); $res = $SqlTool->execute_dql($sql); if (mysql_num_rows($res) != 0) { while ($row = mysql_fetch_assoc($res)) { echo "
".$ch_word . "對應的英文為" . $row['enword']; } } else { echo "查詢沒有這個詞條.
"; echo "回到主頁面"; } //釋放資源 mysql_free_result($res); } ?> ``` 現在來測試一下吧,首先開啟前端頁面,如下圖: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205195651073-85698329.png) 接下來輸入boy進行查詢,結果如下,查詢成功: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205195732214-472148300.png) 因為是案例,所以直接**將前端傳過來的引數沒有做任何處理直接拼接到SQL語句中,這樣是非常危險的!!**,存在SQL注入攻擊,現在我來演示一下,在輸入框中輸入: ` boy' and updatexml(1,concat(0x7e,(select user()),0x7e),1)#` 結果如下圖直接報出使用者!! ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205195829867-2014120850.png) 所以在開發功能時,**要秉持“外部引數皆不可信原則”進行開發**。 #MYSQLI擴充套件 其實mysqli擴充套件是mysql擴充套件的加強版,因為歷史原因,有一些老程式設計師擅長面向過程寫法,所以PHP設計者為mysqli設計了兩套方案,一套面向物件,一套面向過程,甚至一個聊本里可以混著用,不過那樣很怪,下面的案例都是採用面向物件的那套方案。 ##案例 做一個小功能吧,向資料庫中插入資料。先設計一下SQL表,語句如下: ``` create database day1; use day1; create table user1 ( id int(6) unsigned auto_increment primary key, name varchar(20) not null, password varchar(256) not null, email varchar(80) not null, age int(128) not null ); ​ INSERT INTO user1(name,password,email,age) VALUES('Lucia','13568','[email protected]',30); ``` 因為一會兒要插入資料,所以先插入一條,構造好後,開啟資料庫,查詢,發現沒有問題 ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205200404110-559114151.png) 接下來構造mysqli工具類程式碼如下: ```
mysqli=new mysqli($this->host,$this->user,$this->pass,$this->db); if ($this->mysqli->connect_error){ echo "連線失敗"; } $this->mysqli->query("set names utf8"); } //進行select public function execute_dql($sql){ $res=$this->mysqli->query($sql) or die($this->mysqli->error); return $res; } //進行update,insert,delete public function execute_dml($sql){ $res=$this->mysqli->query($sql) or die($this->mysqli->error); if (!$res){ return 0; }else{ if ($this->mysqli->affected_rows>0){ return 1;//成功 }else{ return 2;//沒有行數收影響 } } } } ?> ``` 下面就是前端頁面了,這裡我用表單向後端提交資料,程式碼如下: ```
新增聯絡人





姓名:

密碼:

email:

年齡:

     ``` 效果如下圖: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205200512706-1164450399.png) 然後就是後端的邏輯設計了,程式碼如下: ``` execute_dml($sql); if ($res==1){ echo "新增成功"; }else{ if ($res==0){ echo '新增失敗'; }else{ echo "行數沒有變化"; } } ?> ``` 現在測試一下,我們在表單頁面輸入 **小明,12345678,[email protected],25** 資料,如下圖: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205200613678-458961077.png) 然後提交表單,看看有沒有插入到資料庫中。 我們發現成功插入到資料庫中如下: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205200700937-170151197.png) 關於mysqli擴充套件就說到這裡。 #MySQL批量執行SQL語句 上面簡單介紹了MySQL擴充套件和MySQLI擴充套件,接下來說一說批量執行sql語句。 先提一個需求,如果我們像資料庫批量新增使用者,如果按照之前的辦法一條一條的傳送sql語句來處理,這樣很佔用資源,並且效率低。所以採用批量執行sql語句的方式。接下來用兩個案例來講解,因為增加,修改,刪除操作返回的是布林值,而查詢操作返回的是結果集,所以分來來處理比較好。 ##批量執行dml語句 因為dml返回的是布林值,所以處理起來也比較好處理。先建立表,順便插入一條資料如下: ``` create database test; use test; create table users( id int(8) unsigned auto_increment primary key, name varchar(128) not null, password varchar(256) not null); insert into users(name,password) values('test','13579'); ``` 下面就是批量執行dml操作的程式碼: ``` connect_error){ echo "連線失敗"; } $sqli="insert into users(name,password) values ('小利',md5('13568'));"; //批量執行dml操作時,注意上一級句的;和下一句的.兩個符號 $sqli.="insert into users(name,password) values ('小利',md5('13568'));"; $sqli.="insert into users(name,password) values ('小利和小峰',md5('13568'))"; $b=$mysqli->multi_query($sqli); if (!$b){ echo "插入失敗"; }else{ echo "ok!"; } $mysqli->close(); ?> ``` 然後訪問頁面,返回ok,說明插入到資料庫了,現在開啟資料庫檢視,果然插入進去了,如下圖: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205201221498-134919273.png) ##批量執行dql操作 批量執行dql操作的作用是一次性取回多個結果集,下面看案例程式碼: ``` connect_error){ echo "連線失敗"; } $sqli="select * from users;"; $sqli.="select * from lsp"; //因為multi_query這個函式比較傻,不會去判斷有沒有下一個結果集,所以最後再用more_results函式檢查一下。 if ($mysqli->multi_query($sqli)){ do{ //從mysqli中取出第一個結果集 $result=$mysqli->store_result(); //顯示mysqli $res物件 while ($row=$result->fetch_row()){ foreach ($row as $key=>$val){ echo "--$val"; } echo "
"; } $result->free(); //判斷有沒有下一個結果集,如果沒有退出迴圈 if (!$mysqli->more_results()){ break; } echo "
*************新得結果集
"; } while ($mysqli->next_result()); } ?> ``` 結果如下圖: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205201412422-1307247383.png) 關於MySQL的批量執行sql語句就說到這裡。 #MySQL事務控制 上面簡單介紹了MySQL擴充套件庫,MySQLI擴充套件庫,批量執行SQL語句,接下來說一說MySQL事務控制。 ##資料庫配置 說MySQL事務控制之前,先檢視並修改資料庫引擎,檢視引擎的命令如下: > show engines ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205201732460-144792628.png) 我們發現,只有InnoDB是支援事務的,所以先檢視一下現在得資料庫引擎: ![](https://img2020.cnblogs.com/blog/1996712/202102/1996712-20210205201825726-647444840.png) 發現是MyISAM,我們將它修改為InnoDB,開啟配置檔案my.ini,將“default-storage-engine=MYISAM”改為你想設定的,然後重啟即可。修改成功後,然後下一步就是程式碼實現。 ##案例 我們為什麼需要事務控制呢?想一想,如果這是一個轉賬得場景,是不是需要同時控制住,必須我減金額得同時你加金額,任何一個出錯都得轉賬失敗。也就是說要保持一致。這也是要進行事務控制得必要性。下面看案例程式碼: ``` connect_error){ echo "連線失敗"; } //將提交設定為假,因為事物一旦提交就沒有機會回滾 $mysqli->autocommit(false); $sql1="update person set money=money-3 where id=1"; //這裡第二條語句我故意寫錯表名 $sql2="update persons set money=money+3 where id=2"; $b1=$mysqli->query($sql1); $b2=$mysqli->query($sql2); if (!$b1 || !$b2){ echo "修改失敗,回滾".$mysqli->error; $mysqli->rollback(); }else{ echo "修改成功!"; $mysqli->commit(); } $mysqli->close(); ?> ``` 當我們提交頁面後,查詢資料庫,發現數據沒有變化,說明回滾有效果,事務控制起了效果,事務控制就說到這裡。以上就是本篇文章的全部內容啦,如有錯誤,請