在實(shí)際的開發(fā)中,PHP都是會和數(shù)據(jù)庫一起使用的,因?yàn)樵诤笈_需要有太多的數(shù)據(jù)進(jìn)行保存,而數(shù)據(jù)庫就是一種很好的保存數(shù)據(jù)的地方,我們PHP開發(fā)用到的數(shù)據(jù)庫是關(guān)系型數(shù)據(jù)庫mysql,而PHP和mysql數(shù)據(jù)庫只有連接,我們才能通過php代碼對數(shù)據(jù)庫進(jìn)行操作。
相關(guān)mysql視頻教程推薦:《mysql教程》
PHP的開發(fā)離不開數(shù)據(jù)庫,而在PHP中可以通過html' target='_blank'>MySQLi連接數(shù)據(jù)庫的。但是MySQLi只能連接mysql數(shù)據(jù)庫。同時mysqli是一種面向?qū)ο?/u>的技術(shù)。
MySQLi的特點(diǎn):
效率提高,穩(wěn)定性強(qiáng)。
對數(shù)據(jù)庫進(jìn)行操作。
支持面向?qū)ο箝_發(fā)。同時也支持面向過程開發(fā)。
想要在PHP中使用MySQLi功能需要在php.ini中加載php_mysql.dll這個動態(tài)連接文件。
操作流程在mysql中創(chuàng)建一個數(shù)據(jù)庫當(dāng)做操作對象。
打開PHP擴(kuò)展庫
創(chuàng)建mysqli的對象
$mysql = new MySQLi(主機(jī),賬號,密碼,數(shù)據(jù)庫,端口號);
里面有幾個參數(shù)。
設(shè)置字符集
$mysql -> set_charset('utf8');編寫sql語句并且執(zhí)行。這個sql語句可以是dml,dql語句
$mysql -> query($sql);
將取回的結(jié)果顯示頁面取出數(shù)據(jù)有四種方式(assoc、row、object、array)我們一般使用assoc這種方式。但是如果是dml語句則返回布爾值。
$res -> fetch_assoc();
釋放結(jié)果集。關(guān)閉連接。
$res -> free();$mysqli -> close();
當(dāng)我們在進(jìn)行插入,刪除,修改(dml)時,返回的是一個布爾值,但是我們并不知道里面有沒有變化。可以用$mysqli -> affected_rows,mysqli里面的屬性進(jìn)行判斷,返回的結(jié)果是sql語句對數(shù)據(jù)表的影響行數(shù)。
<?php //使用面向?qū)ο筮M(jìn)行數(shù)據(jù)庫的連接,在創(chuàng)建對象的時候就自動的連接數(shù)據(jù) $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷數(shù)據(jù)庫是否連接 if($mySQLi -> connect_errno){ die('連接錯誤' . $mySQLi -> connect_error); } //設(shè)置字符集 $mySQLi -> set_charset('utf8'); //編寫sql語句并執(zhí)行 $sql = "select * from good"; //發(fā)送sql語句并執(zhí)行,如果是select語句,返回的是一個對象,其他的返回來一個boolean. $res = $mySQLi -> query($sql); echo '<pre>'; //使用$res對象里面的fetch_assoc()取出里面的數(shù)據(jù). // while($row = $res->fetch_assoc()){ // var_dump($row); // } // 使用fetch_row()方法 // while($row = $res -> fetch_row()){ // var_dump($row); // } //使用fetch_array(); // while($row = $res -> fetch_array()){ // var_dump($row); // } //fetch_object(); while($row = $res -> fetch_object()){ var_dump($row); } $res -> free(); $mySQLi -> close();
上面的代碼就是使用mysqli的具體實(shí)現(xiàn)。mysqli是使用面向?qū)ο蟮乃枷雭韺懙摹jP(guān)于其中的方法。
$mySQLi -> connect_errno返回連接的最后一次連接的錯誤,如果返回0則連接成功,返回非0則連接失敗
$mySQLi -> connect_error返回連接錯誤的原因。
$mySQLi -> set_charset(‘utf8’);設(shè)置字符集,里面的參數(shù)根據(jù)自己的情況寫。
sql)當(dāng)寫完一個sql語句后,使用這個方法傳遞sql語句到數(shù)據(jù)庫執(zhí)行。并且根據(jù)sql語句的類型不同,返回不同的結(jié)果上面返回的是一個mysqli_result對象
mysqli_result對象代表從一個數(shù)據(jù)庫查詢中獲取的結(jié)果集。也就是進(jìn)行sql查詢從數(shù)據(jù)庫中返回的結(jié)果。得到里面的結(jié)果mysqli/_result對象提供了四種方法,他們有不同的區(qū)別。
$mysqli_result -> fetch_assoc()返回結(jié)果集中的一條數(shù)據(jù),這條數(shù)據(jù)是一個關(guān)聯(lián)數(shù)組,鍵是數(shù)據(jù)庫表的字段名,值是表里面的值。
array(3) { ["id"]=> string(1) "1" ["name"]=> string(6) "張三" ["price"]=> string(7) "1234.60"}$mysqli_result -> fetch_row()返回的也是結(jié)果集中的一條數(shù)據(jù),這條數(shù)據(jù)是一個索引數(shù)組。
array(3) { [0]=> string(1) "1" [1]=> string(6) "張三" [2]=> string(7) "1234.60"}$mysqli_result = $res -> fetch_array()返回的一個數(shù)組,是一個關(guān)聯(lián)數(shù)組和索引數(shù)組組合的數(shù)組。
array(6) { [0]=> string(1) "1" ["id"]=> string(1) "1" [1]=> string(6) "張三" ["name"]=> string(6) "張三" [2]=> string(7) "1234.60" ["price"]=> string(7) "1234.60"}$mysqli_result = $res -> fetch_object()返回一個有一條數(shù)據(jù)封裝成的對象。這個對象是使用了PHP的內(nèi)置標(biāo)準(zhǔn)類。表的字段是類的屬性。
object(stdClass)#3 (3) { ["id"]=> string(1) "1" ["name"]=> string(6) "張三" ["price"]=> string(7) "1234.60"}mysqli處理mysql的事務(wù)一共提供了三種方式開啟事務(wù)。
$mySQLi -> query(‘start transaction’);
$mySQLi -> query(‘set autocommit = false’);
$mySQLi -> begin_transaction();
<?php //使用面向?qū)ο筮M(jìn)行數(shù)據(jù)庫的連接,在創(chuàng)建對象的時候就自動的連接數(shù)據(jù) $mySQLi = new MySQLi('localhost','root','123456','test',3306);//判斷數(shù)據(jù)庫是否連接if($mySQLi -> connect_errno){ die('連接錯誤' . $mySQLi -> connect_error);}//設(shè)置字符集$mySQLi -> set_charset('utf8');//編寫sql語句$sql1 = "insert into good values(null,'武松',2345.7)";$sql2 = "update good set price = 3546.67 where id = 2";//開啟事務(wù)$mySQLi -> query('start transaction');// $mySQLi -> query('set autocommit = false'); //第二種方式// $mySQLi -> begin_transaction();//第三種方式//發(fā)送sql語句,因?yàn)閟ql語句是插入和修改語句,返回的結(jié)果是一個布爾值。$res1 = $mySQLi -> query($sql1);$res2 = $mySQLi -> query($sql2);if($res1 && $res2){ echo '操作成功'; //提交事務(wù)。 $mySQLi -> commit();}else{ echo '操作失敗'; //進(jìn)行數(shù)據(jù)的回滾 $mySQLi -> rollback();}$mySQLi -> close();當(dāng)語句執(zhí)行失敗的時候可以進(jìn)行數(shù)據(jù)的回滾。
mysqli批量執(zhí)行sql語句在用PHP操作數(shù)據(jù)庫時,有時候我們需要一次性執(zhí)行多條sql語句,比如批量增加用戶,這時如果單條單條的向mysql數(shù)據(jù)庫發(fā)送sql指令,效率不高,這時可以考慮使用批量執(zhí)行sql語句的方式。
mysqli批量執(zhí)行sql語句的語法:
$sql = "sql語句1;sql語句2;sql語句3";$res = $mysqli -> multi_query();
當(dāng)然對于批量操作,有不同的返回結(jié)果。
如果批量執(zhí)行的是dml操作語句,那么 返回結(jié)果是布爾值
如果批量執(zhí)行的是dql(select)操作語句,那么 返回結(jié)果是多個結(jié)果集.
批量執(zhí)行dml語句:
<?php //使用面向?qū)ο筮M(jìn)行數(shù)據(jù)庫的連接,在創(chuàng)建對象的時候就自動的連接數(shù)據(jù) $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷數(shù)據(jù)庫是否連接 if($mySQLi -> connect_errno){ die('連接錯誤' . $mySQLi -> connect_error); } //設(shè)置字符集 $mySQLi -> set_charset('utf8'); $sql = "insert into good values(null,'孫悟空',1234.8);"; $sql .= "insert into good values(null,'豬八戒',4564.3)"; //進(jìn)行批量的sql語句執(zhí)行。 $res = $mySQLi -> multi_query($sql); if($res){ echo '添加成功'; }else{ echo '添加失敗' . $mySQLi -> error; } $mySQLi -> close();
在進(jìn)行dml批量操作時,如果有一個語句錯誤,那么后面的sql語句就不執(zhí)行了,并且在進(jìn)行dml批量操作時,返回的布爾值的結(jié)果,就是第一條sql語句執(zhí)行的結(jié)果。那么如果第一條語句執(zhí)行成功,后面的語句執(zhí)行失敗,得到的布爾值也是true。
批量執(zhí)行dql語句
<?php //使用面向?qū)ο筮M(jìn)行數(shù)據(jù)庫的連接,在創(chuàng)建對象的時候就自動的連接數(shù)據(jù) $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷數(shù)據(jù)庫是否連接 if($mySQLi -> connect_errno){ die('連接錯誤' . $mySQLi -> connect_error); } //設(shè)置字符集 $mySQLi -> set_charset('utf8'); $sql = 'select id,name from good;'; $sql .= 'select price from good'; echo '<pre>'; //這里返回的記過是一個布爾值。 if($mySQLi -> multi_query($sql)){ //得到里面的數(shù)據(jù) do{ //通過這個函數(shù)返回查找的結(jié)果集,返回的是一個mysqli_result對象。 $res = $mySQLi -> store_result(); while($row = $res -> fetch_assoc()){ var_dump($row); } //判斷是否還有結(jié)果。如果沒有退出循環(huán)。 if(!$mySQLi -> more_results()){ break; } //相當(dāng)于一個指針,指向下一個結(jié)果。 }while($mySQLi -> next_result()); }else{ echo '執(zhí)行失敗'; } $mySQLi -> close();
當(dāng)執(zhí)行的批量語句是dql語句時,數(shù)據(jù)庫會返回查找的結(jié)果。通過mysqli -> store_result()這個方法返回mysqli->result對象。上面的代碼中批量執(zhí)行了兩句select,數(shù)據(jù)庫會返回兩個結(jié)果集,而通過store_result()方法返回的是一條select語句的結(jié)果。當(dāng)顯示完數(shù)據(jù)后通過more_results()方法進(jìn)行判斷是否還有數(shù)據(jù)。如果沒有,跳出循環(huán)。有數(shù)據(jù)的話通過next_result()方法指向下一個結(jié)果集。
more_results()方法是判斷有沒有下一個結(jié)果集,但是結(jié)果集的指針并不會執(zhí)行下一個結(jié)果集。而next_result()方法是把指針向前挪移一位。
mysqli預(yù)處理技術(shù)在PHP操作數(shù)據(jù)庫中使用預(yù)處理技術(shù)可以大大提高我們的sql語句執(zhí)行速度。關(guān)于sql語句在dbms中的執(zhí)行時間消耗的步驟如圖:

在其中dbms進(jìn)行分析sql語句的時間大約占20%,而預(yù)處理就是把分析sql語句這個步驟省略,從而提高執(zhí)行sql語句效率。預(yù)處理就是通過把我們想傳入的參數(shù)使用占位符?來表示,通過預(yù)處理對象綁定真實(shí)的參數(shù)。
<?php //使用面向?qū)ο筮M(jìn)行數(shù)據(jù)庫的連接,在創(chuàng)建對象的時候就自動的連接數(shù)據(jù) $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷數(shù)據(jù)庫是否連接 if($mySQLi -> connect_errno){ die('連接錯誤' . $mySQLi -> connect_error); } //設(shè)置字符集 $mySQLi -> set_charset('utf8'); $sql = "INSERT INTO good VALUES(?,?,?)"; //通過prepare()方法返回一個預(yù)處理的對象。 $mysql_stmt = $mySQLi -> prepare($sql); $id = 18; $name = '松江'; $price = 2344.45; //綁定參數(shù) $mysql_stmt -> bind_param('iss',$id,$name,$price); //通過預(yù)處理對象執(zhí)行。 if($mysql_stmt -> execute()){ echo '執(zhí)行成功'; }else{ echo '執(zhí)行失敗'; } //當(dāng)我們還想添加一條數(shù)據(jù)時,dbms不用分析sql語句。 $id = 19; $name = '武松'; $price = 2346.45; //綁定參數(shù), $mysql_stmt -> bind_param('iss',$id,$name,$price); //通過預(yù)處理對象執(zhí)行。 if($mysql_stmt -> execute()){ echo '執(zhí)行成功'; }else{ echo '執(zhí)行失敗'; }
在上面的代碼中,通過mysqli -> prepare()方法得到預(yù)處理對象,而sql語句里面的參數(shù)是通過占位符?表示。得到預(yù)處理對象后通過定義想傳遞的參數(shù),使用bind_param()方法進(jìn)行參數(shù)的綁定。然后通過execute()方法進(jìn)行執(zhí)行,之后如果執(zhí)行同樣的參數(shù),只要把參數(shù)定義完之后,進(jìn)行綁定執(zhí)行就行了。
bind_param(參數(shù)1,參數(shù)2):這個方法是綁定參數(shù)的方法,里面一共有兩個參數(shù),第一個參數(shù)是我們綁定參數(shù)的類型,我們一般用到三個值:
i int類型
d double類型,也就是小數(shù)類型
s 字符串類型
第二個參數(shù)是對象第一個參數(shù)的變量的值。
上面的是插入的時候時候預(yù)處理,在dml,dql都可以使用預(yù)處理。
DaoMysqli.class.php開發(fā)PHP是面向?qū)ο蟮恼Z言,而在操作數(shù)據(jù)庫時,我們可以把一些功能進(jìn)行封裝,創(chuàng)建成對象。使用DaoMySqli這個封裝好的類,可以簡化我們的項目,體現(xiàn)面向?qū)ο蟮乃枷搿?/p>
DaoMysqli.class這個類的實(shí)現(xiàn):
使用單例模式控制資源,始終只有一個對象。
使用final關(guān)鍵字修飾類防止被繼承。
使用魔術(shù)方法__clone(),防止克隆。
通過在類里面創(chuàng)建mysqli對象,連接數(shù)據(jù)庫。
通過mysqli在類里面進(jìn)行數(shù)據(jù)的增刪改查等操作,把操作過程封裝起來。
//把構(gòu)造函數(shù)私有化,在類外部創(chuàng)建不了對象。 private function __construct($canshu){ $this -> initMySQLi($canshu); }public static function getInstrance($canshu){ if(!(self::$daoMysqli instanceof DaoMysqli)){ self::$daoMysqli = new DaoMysqli($canshu); } return self::$daoMysqli;}
把構(gòu)造函數(shù)私有化,在類外面不能創(chuàng)建對象。同時提供一個創(chuàng)建對象的靜態(tài)方法,在靜態(tài)里面創(chuàng)建DaoMysqli對象和mysqli對象。
防止繼承、克隆//防止繼承。final class DaoMysqli{//防止克隆。private function __clone(){}創(chuàng)建mysqli對象//初始化mysqli對象。 private function initMySQLi($canshu){ $this -> host = isset($canshu[0]) ? $canshu[0] : ''; $this -> user = isset($canshu[1]) ? $canshu[1] : ''; $this -> password = isset($canshu[2]) ? $canshu[2] : ''; $this -> db_name = isset($canshu[3]) ? $canshu[3] : ''; //如果端口號沒有傳入,默認(rèn)是3306 //編碼默認(rèn)是utf8。 $this -> duankou = isset($canshu[4]) ? $canshu[4] : 3306; $this -> charset = isset($canshu[5]) ? $canshu[5] : 'utf8'; if($this -> host == '' || $this -> user == '' || $this -> password == '' || $this -> db_name == ''){ die('參數(shù)不能為空'); } $this -> mySQLi = new MySQLi($this -> host,$this -> user,$this -> password,$this -> db_name,$this -> duankou); if($this -> mySQLi -> connect_errno){ die('連接錯誤,錯誤信息是' . $this -> mySQLi -> connect_error); } $this -> mySQLi -> set_charset($this -> charset); }
在類里面通過調(diào)用私有的構(gòu)造函數(shù)進(jìn)行對象的創(chuàng)建。
通過mysqli對象操作數(shù)據(jù)庫//dql操作返回一個數(shù)組。 public function mySelect($sql){ if($res = $this -> mySQLi -> query($sql)){ $res = $this -> mySQLi -> query($sql); $rows = array(); while($row = $res -> fetch_assoc()){ $rows[] = $row; } return $rows; }else{ die('錯誤,' . $this -> mySQLi -> error); } } //dml操作。 public function dml($sql){ return $this -> mySQLi -> query($sql); }當(dāng)時dql語句時,可以在方法里面進(jìn)行處理,直接把數(shù)據(jù)解析出來,放到一個數(shù)組里面進(jìn)行返回。
源代碼<?phpfinal class DaoMysqli{ private static $daoMysqli; //類本身對象 private $mySQLi; //mysqli對象,在類里面操作數(shù)據(jù)庫。 private $host; //主機(jī)名 private $user;//用戶名 private $password;//密碼 private $db_name;//數(shù)據(jù)庫名字 private $duankou; //數(shù)據(jù)庫占用的端口號。 private $charset; //使用的字符集 //把構(gòu)造函數(shù)私有化,在類外部創(chuàng)建不了對象。 private function __construct($canshu){ $this -> initMySQLi($canshu); } //初始化mysqli對象。 private function initMySQLi($canshu){ $this -> host = isset($canshu[0]) ? $canshu[0] : ''; $this -> user = isset($canshu[1]) ? $canshu[1] : ''; $this -> password = isset($canshu[2]) ? $canshu[2] : ''; $this -> db_name = isset($canshu[3]) ? $canshu[3] : ''; //如果端口號沒有傳入,默認(rèn)是3306 //編碼默認(rèn)是utf8。 $this -> duankou = isset($canshu[4]) ? $canshu[4] : 3306; $this -> charset = isset($canshu[5]) ? $canshu[5] : 'utf8'; if($this -> host == '' || $this -> user == '' || $this -> password == '' || $this -> db_name == ''){ die('參數(shù)不能為空'); } $this -> mySQLi = new MySQLi($this -> host,$this -> user,$this -> password,$this -> db_name,$this -> duankou); if($this -> mySQLi -> connect_errno){ die('連接錯誤,錯誤信息是' . $this -> mySQLi -> connect_error); } $this -> mySQLi -> set_charset($this -> charset); } //防止克隆。 private function __clone(){} public static function getInstrance($canshu){ if(!(self::$daoMysqli instanceof DaoMysqli)){ self::$daoMysqli = new DaoMysqli($canshu); } return self::$daoMysqli; } //dql操作返回一個數(shù)組。 public function mySelect($sql){ if($res = $this -> mySQLi -> query($sql)){ $res = $this -> mySQLi -> query($sql); $rows = array(); while($row = $res -> fetch_assoc()){ $rows[] = $row; } return $rows; }else{ die('錯誤,' . $this -> mySQLi -> error); } } //dml操作。 public function dml($sql){ return $this -> mySQLi -> query($sql); }}測試<?php require './DaoMysqli.php'; $canshu = array('localhost','root','123456','test','3306'); $dao = DaoMysqli::getInstrance($canshu); $sql = "select * from good"; $res = $dao -> mySelect($sql); foreach ($res as $value) { var_dump($value); echo '<br>'; }參數(shù)是通過一個數(shù)組傳進(jìn)去的。

PHP操作數(shù)據(jù)庫的方法中很多中,mysqli只是其中的一種,這種操作方式我們更容易理解和掌握,但是mysqli還是有一些不足,我們在PHP開發(fā)中有時候使用的數(shù)據(jù)庫并不是mysql數(shù)據(jù)庫,而是別的數(shù)據(jù)庫,這時,mysqli這種方式就顯得有些無力,mysqli只是純粹的操作mysql數(shù)據(jù)庫,對于別的數(shù)據(jù)庫沒有辦法操作。
以上就是PHP基礎(chǔ)教程十四之使用MySqli操作數(shù)據(jù)庫的內(nèi)容,更多相關(guān)內(nèi)容請關(guān)注PHP (m.survivalescaperooms.com)!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
|
新聞熱點(diǎn)
疑難解答