前言
在實際的開發中,PHP都是會和資料庫一起使用的,因為在後台需要有太多的資料進行儲存,而資料庫就是一種很好的儲存資料的地方,我們PHP開發用到的資料庫是關係型資料庫mysql,而PHP和mysql資料庫只有串連,我們才能通過php代碼對資料庫進行操作。
MySqli
PHP的開發離不開資料庫,而在PHP中可以通過MySQLi串連資料庫的。但是MySQLi只能串連mysql資料庫。同時mysqli是一種物件導向的技術。
MySQLi的特點:
效率提高,穩定性強。
對資料庫進行操作。
支援物件導向開發。同時也支援面向過程開發。
想要在PHP中使用MySQLi功能需要在php.ini中載入php_mysql.dll這個動態串連檔案。
操作流程
在mysql中建立一個資料庫當做操作對象。
開啟PHP擴充庫
建立mysqli的對象
$mysql = new MySQLi(主機,帳號,密碼,資料庫,連接埠號碼);
裡面有幾個參數。
設定字元集
$mysql -> set_charset('utf8');
編寫sql語句並且執行。這個sql語句可以是dml,dql語句
$mysql -> query($sql);
將取回的結果顯示頁面取出資料有四種方式(assoc、row、object、array)我們一般使用assoc這種方式。但是如果是dml語句則返回布爾值。
$res -> fetch_assoc();
釋放結果集。關閉串連。
$res -> free();$mysqli -> close();
當我們在進行插入,刪除,修改(dml)時,返回的是一個布爾值,但是我們並不知道裡面有沒有變化。可以用$mysqli -> affected_rows,mysqli裡面的屬性進行判斷,返回的結果是sql語句對資料表的影響行數。
<?php //使用物件導向進行資料庫的串連,在建立對象的時候就自動的串連資料 $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷資料庫是否串連 if($mySQLi -> connect_errno){ die('串連錯誤' . $mySQLi -> connect_error); } //設定字元集 $mySQLi -> set_charset('utf8'); //編寫sql語句並執行 $sql = "select * from good"; //發送sql語句並執行,如果是select語句,返回的是一個對象,其他的返回來一個boolean. $res = $mySQLi -> query($sql); echo '<pre>'; //使用$res對象裡面的fetch_assoc()取出裡面的資料. // 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的具體實現。mysqli是使用物件導向的思想來寫的。關於其中的方法。
$mySQLi -> connect_errno返回串連的最後一次串連的錯誤,如果返回0則串連成功,返回非0則串連失敗
$mySQLi -> connect_error返回串連錯誤的原因。
$mySQLi -> set_charset(‘utf8’);設定字元集,裡面的參數根據自己的情況寫。
- sql)當寫完一個sql語句後,使用這個方法傳遞sql語句到資料庫執行。並且根據sql語句的類型不同,返回不同的結果上面返回的是一個mysqli_result對象
mysqli_result對象代表從一個資料庫查詢中擷取的結果集。也就是進行sql查詢從資料庫中返回的結果。得到裡面的結果mysqli/_result對象提供了四種方法,他們有不同的區別。
$mysqli_result -> fetch_assoc()返回結果集中的一條資料,這條資料是一個關聯陣列,鍵是資料庫表的欄位名,值是表裡面的值。
array(3) { ["id"]=> string(1) "1" ["name"]=> string(6) "張三" ["price"]=> string(7) "1234.60"}
$mysqli_result -> fetch_row()返回的也是結果集中的一條資料,這條資料是一個索引數組。
array(3) { [0]=> string(1) "1" [1]=> string(6) "張三" [2]=> string(7) "1234.60"}
$mysqli_result = $res -> fetch_array()返回的一個數組,是一個關聯陣列和索引數組組合的數組。
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()返回一個有一條資料封裝成的對象。這個對象是使用了PHP的內建標準類。表的欄位是類的屬性。
object(stdClass)#3 (3) { ["id"]=> string(1) "1" ["name"]=> string(6) "張三" ["price"]=> string(7) "1234.60"}
mysqli的交易處理
mysqli處理mysql的事務一共提供了三種方式開啟事務。
$mySQLi -> query(‘start transaction’);
$mySQLi -> query(‘set autocommit = false’);
$mySQLi -> begin_transaction();
<?php //使用物件導向進行資料庫的串連,在建立對象的時候就自動的串連資料 $mySQLi = new MySQLi('localhost','root','123456','test',3306);//判斷資料庫是否串連if($mySQLi -> connect_errno){ die('串連錯誤' . $mySQLi -> connect_error);}//設定字元集$mySQLi -> set_charset('utf8');//編寫sql語句$sql1 = "insert into good values(null,'武松',2345.7)";$sql2 = "update good set price = 3546.67 where id = 2";//開啟事務$mySQLi -> query('start transaction');// $mySQLi -> query('set autocommit = false'); //第二種方式// $mySQLi -> begin_transaction();//第三種方式//發送sql語句,因為sql語句是插入和修改語句,返回的結果是一個布爾值。$res1 = $mySQLi -> query($sql1);$res2 = $mySQLi -> query($sql2);if($res1 && $res2){ echo '操作成功'; //提交事務。 $mySQLi -> commit();}else{ echo '操作失敗'; //進行資料的復原 $mySQLi -> rollback();}$mySQLi -> close();
當語句執行失敗的時候可以進行資料的復原。
mysqli批量執行sql語句
在用PHP操作資料庫時,有時候我們需要一次性執行多條sql語句,比如批量增加使用者,這時如果單條單條的向mysql資料庫發送sql指令,效率不高,這時可以考慮使用批量執行sql語句的方式。
mysqli批量執行sql語句的文法:
$sql = "sql語句1;sql語句2;sql語句3";$res = $mysqli -> multi_query();
當然對於大量操作,有不同的返回結果。
如果批量執行的是dml動作陳述式,那麼 返回結果是布爾值
如果批量執行的是dql(select)動作陳述式,那麼 返回結果是多個結果集.
批量執行dml語句:
<?php //使用物件導向進行資料庫的串連,在建立對象的時候就自動的串連資料 $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷資料庫是否串連 if($mySQLi -> connect_errno){ die('串連錯誤' . $mySQLi -> connect_error); } //設定字元集 $mySQLi -> set_charset('utf8'); $sql = "insert into good values(null,'孫悟空',1234.8);"; $sql .= "insert into good values(null,'豬八戒',4564.3)"; //進行批量的sql語句執行。 $res = $mySQLi -> multi_query($sql); if($res){ echo '添加成功'; }else{ echo '添加失敗' . $mySQLi -> error; } $mySQLi -> close();
在進行dml大量操作時,如果有一個語句錯誤,那麼後面的sql語句就不執行了,並且在進行dml大量操作時,返回的布爾值的結果,就是第一條sql語句執行的結果。那麼如果第一條語句執行成功,後面的語句執行失敗,得到的布爾值也是true。
批量執行dql語句
<?php //使用物件導向進行資料庫的串連,在建立對象的時候就自動的串連資料 $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷資料庫是否串連 if($mySQLi -> connect_errno){ die('串連錯誤' . $mySQLi -> connect_error); } //設定字元集 $mySQLi -> set_charset('utf8'); $sql = 'select id,name from good;'; $sql .= 'select price from good'; echo '<pre>'; //這裡返回的記過是一個布爾值。 if($mySQLi -> multi_query($sql)){ //得到裡面的資料 do{ //通過這個函數返回尋找的結果集,返回的是一個mysqli_result對象。 $res = $mySQLi -> store_result(); while($row = $res -> fetch_assoc()){ var_dump($row); } //判斷是否還有結果。如果沒有退出迴圈。 if(!$mySQLi -> more_results()){ break; } //相當於一個指標,指向下一個結果。 }while($mySQLi -> next_result()); }else{ echo '執行失敗'; } $mySQLi -> close();
當執行的批量語句是dql語句時,資料庫會返回尋找的結果。通過mysqli -> store_result()這個方法返回mysqli->result對象。上面的代碼中批量執行了兩句select,資料庫會返回兩個結果集,而通過store_result()方法返回的是一條select語句的結果。當顯示完資料後通過more_results()方法進行判斷是否還有資料。如果沒有,跳出迴圈。有資料的話通過next_result()方法指向下一個結果集。
more_results()方法是判斷有沒有下一個結果集,但是結果集的指標並不會執行下一個結果集。而next_result()方法是把指標向前挪移一位。
mysqli預先處理技術
在PHP操作資料庫中使用預先處理技術可以大大提高我們的sql語句執行速度。關於sql語句在dbms中的執行時間消耗的步驟
在其中dbms進行分析sql語句的時間大約佔20%,而預先處理就是把分析sql語句這個步驟省略,從而提高執行sql語句效率。預先處理就是通過把我們想傳入的參數使用預留位置?來表示,通過預先處理對象綁定真實的參數。
<?php //使用物件導向進行資料庫的串連,在建立對象的時候就自動的串連資料 $mySQLi = new MySQLi('localhost','root','123456','test',3306); //判斷資料庫是否串連 if($mySQLi -> connect_errno){ die('串連錯誤' . $mySQLi -> connect_error); } //設定字元集 $mySQLi -> set_charset('utf8'); $sql = "INSERT INTO good VALUES(?,?,?)"; //通過prepare()方法返回一個預先處理的對象。 $mysql_stmt = $mySQLi -> prepare($sql); $id = 18; $name = '松江'; $price = 2344.45; //綁定參數 $mysql_stmt -> bind_param('iss',$id,$name,$price); //通過預先處理對象執行。 if($mysql_stmt -> execute()){ echo '執行成功'; }else{ echo '執行失敗'; } //當我們還想添加一條資料時,dbms不用分析sql語句。 $id = 19; $name = '武松'; $price = 2346.45; //綁定參數, $mysql_stmt -> bind_param('iss',$id,$name,$price); //通過預先處理對象執行。 if($mysql_stmt -> execute()){ echo '執行成功'; }else{ echo '執行失敗'; }
在上面的代碼中,通過mysqli -> prepare()方法得到預先處理對象,而sql語句裡面的參數是通過預留位置?表示。得到預先處理對象後通過定義想傳遞的參數,使用bind_param()方法進行參數的綁定。然後通過execute()方法進行執行,之後如果執行同樣的參數,只要把參數定義完之後,進行綁定執行就行了。
bind_param(參數1,參數2):這個方法是綁定參數的方法,裡面一共有兩個參數,第一個參數是我們綁定參數的類型,我們一般用到三個值:
上面的是插入的時候時候預先處理,在dml,dql都可以使用預先處理。
DaoMysqli.class.php開發
PHP是物件導向的語言,而在操作資料庫時,我們可以把一些功能進行封裝,建立成對象。使用DaoMySqli這個封裝好的類,可以簡化我們的項目,體現物件導向的思想。
DaoMysqli.class這個類的實現:
使用單例模式控制資源,始終只有一個對象。
使用final關鍵字修飾類防止被繼承。
使用魔術方法__clone(),防止複製。
通過在類裡面建立mysqli對象,串連資料庫。
通過mysqli在類裡面進行資料的增刪改查等操作,把操作過程封裝起來。
單例模式
//把建構函式私人化,在類外部建立不了對象。 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;}
把建構函式私人化,在類外面不能建立對象。同時提供一個建立對象的靜態方法,在靜態裡面建立DaoMysqli對象和mysqli對象。
防止繼承、複製
//防止繼承。final class DaoMysqli{//防止複製。private function __clone(){}
建立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] : ''; //如果連接埠號碼沒有傳入,預設是3306 //編碼預設是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('參數不可為空'); } $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); }
在類裡面通過調用私人的建構函式進行對象的建立。
通過mysqli對象操作資料庫
//dql操作返回一個數組。 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); }
當時dql語句時,可以在方法裡面進行處理,直接把資料解析出來,放到一個數組裡面進行返回。
原始碼
<?phpfinal class DaoMysqli{ private static $daoMysqli; //類本身對象 private $mySQLi; //mysqli對象,在類裡面操作資料庫。 private $host; //主機名稱 private $user;//使用者名稱 private $password;//密碼 private $db_name;//資料庫名字 private $duankou; //資料庫佔用的連接埠號碼。 private $charset; //使用的字元集 //把建構函式私人化,在類外部建立不了對象。 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] : ''; //如果連接埠號碼沒有傳入,預設是3306 //編碼預設是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('參數不可為空'); } $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操作返回一個數組。 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>'; }
參數是通過一個數組傳進去的。
總結
PHP操作資料庫的方法中很多中,mysqli只是其中的一種,這種操作方式我們更容易理解和掌握,但是mysqli還是有一些不足,我們在PHP開發中有時候使用的資料庫並不是mysql資料庫,而是別的資料庫,這時,mysqli這種方式就顯得有些無力,mysqli只是純粹的操作mysql資料庫,對於別的資料庫沒有辦法操作。
以上就是PHP基礎教程十四之使用MySqli操作資料庫的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!