在實際的開發中,PHP都是會和資料庫一起使用的,因為在後台需要有太多的資料來保存,而資料庫就是一個很好的保存資料的地方,我們PHP開發用到的資料庫是關係型資料庫mysql,而PHP和mysql資料庫只有連接,我們才能透過php程式碼對資料庫進行操作。
相關mysql影片教學推薦:《mysql教學》
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 class="brush:php;toolbar:false">'; //使用$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處理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();
當語句執行失敗的時候可以進行資料的回滾。
在用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 class="brush:php;toolbar:false">'; //这里返回的记过是一个布尔值。 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()方法是把指针向前挪移一位。
在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):这个方法是绑定参数的方法,里面一共有两个参数,第一个参数是我们绑定参数的类型,我们一般用到三个值:
i int类型
d double类型,也就是小数类型
s 字符串类型
第二个参数是对象第一个参数的变量的值。
上面的是插入的时候时候预处理,在dml,dql都可以使用预处理。
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对象。 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); }
在类里面通过调用私有的构造函数进行对象的创建。
//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语句时,可以在方法里面进行处理,直接把数据解析出来,放到一个数组里面进行返回。
<?php final 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操作資料庫的內容,更多相關內容請關注PHP中文網(www.php.cn)!