1、mysqli類的操做與使用php
一、建立一張mysql的新表以供測試使用html
CREATE TABLE IF NOT EXISTS `user`( id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT "用戶ID", name VARCHAR(30) NOT NULL DEFAULT '' COMMENT "用戶名", password CHAR(30) NOT NULL COMMENT "密碼", email VARCHAR(100) NOT NULL UNIQUE DEFAULT '' COMMENT "郵箱", birthday DATE NOT NULL DEFAULT '2000-1-1' COMMENT "出生日期", age TINYINT UNSIGNED NOT NULL COMMENT "年齡" )CHARSET=utf8 ENGINE=INNODB;
二、利用mysqli創建鏈接mysql
new Mysqli(主機名,用戶名,密碼,數據庫名,端口號)sql
$config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new Mysqli($config['host'], $config['user'], $config['password'],$config['dbname'], $config['port']); //若是沒有錯誤則返回0若是有錯誤,那麼返回對應的錯誤編號 if($mysqli->connect_errno) { die('鏈接錯誤,錯誤信息是'.$mysqli->connect_error); } //設置字符集 $mysqli->set_charset('utf8'); //執行查詢操做,若是要查看執行的錯誤那麼能夠用Mysqli->error $res = $mysqli->query('SELECT * FROM `user`'); //把mysql對象轉成結果並還條打印 while($row = $res->fetch_assoc()) { var_dump($row); } //釋放結果集 $res->free(); //關閉數據庫 $mysqli->close();
三、mysqli 的使用細節說明數據庫
mysqli_result::fetch_assoc => 返回的是一個關聯數組(推薦使用)數組
mysqli_result::fetch_array => 返回的是一個關聯數組以及索引數組測試
mysqli_result::fetch_row => 返回的是一個索引數組fetch
mysqli_result::fetch_object => 返回的是一個對象this
mysqli_result::data_seek(0) => 重置Mysql查詢的指針爲0;spa
用法如以2點的例子同樣
若是想獲取自增加的ID用mysqli->insert_id便可以
四、mysql 查詢的預處理
<?php header('content-type:text/html;charset=utf8'); $config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new Mysqli($config['host'], $config['user'], $config['password'],$config['dbname'], $config['port']); //若是沒有錯誤則返回0若是有錯誤,那麼返回對應的錯誤編號 if($mysqli->connect_errno) { die('鏈接錯誤,錯誤信息是'.$mysqli->connect_error); } //設置字符集 $mysqli->set_charset('utf8'); $sql = 'SELECT `id`, `name`, `age` FROM `user` WHERE `age`>?'; //進行預處理 $res = $mysqli->prepare($sql); //假定id的值爲20; $id = 20; //進行值的綁定 $res->bind_param('i', $id); //進行結果綁定 $res->bind_result($myId, $myName, $myAge); //預處理執行 if($res->execute()) { while($res->fetch()) { echo $myId,$myName,$myAge; //輸出2bbb21 } } $res->free_result(); $res->close(); $mysqli->close(); ?>
五、mysqli的批量查詢操做
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); $config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new mysqli($config['host'], $config['user'], $config['password'], $config['dbname'], $config['port']); if($mysqli->connect_errno) { die('鏈接錯誤'.$mysqli->connect_error); } $mysqli->set_charset('utf8'); $sql = sprintf('%s;%s;%s','SELECT * FROM `student`', 'SELECT * FROM `class`', 'SELECT * FROM `department`'); if($mysqli->multi_query($sql)) { do{ $res = $mysqli->store_result(); while($row = $res->fetch_assoc()) { var_dump($row); } $res->free(); //判斷是否還有更多的結果集,若是有返回true,若是沒有則返回false; if(!$mysqli->more_results()) { break; } //把指針指向下一個結果集 }while($mysqli->next_result()); } else { echo '執行失敗,錯誤碼是'.$mysqli->error; } ?>
注意:mysqli進行批量操做的時候,查詢與增刪改要分開操做,不然容易發生錯誤
六、mysqli的增刪改操做
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); $config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new Mysqli($config['host'], $config['user'], $config['password'],$config['dbname'], $config['port']); //若是沒有錯誤則返回0若是有錯誤,那麼返回對應的錯誤編號 if($mysqli->connect_errno) { die('鏈接錯誤,錯誤信息是'.$mysqli->connect_error); } //設置字符集 $mysqli->set_charset('utf8'); //$sql = 'INSERT INTO `student` (`name`, `age`, `classid`) VALUES ("test", 30, 1)'; $sql = 'UPDATE `student` SET `age`= 18, `name` = "ok" WHERE `studentid` = 26'; //$sql = 'DELETE FROM `student` WHERE `studentid` = 25'; $res = $mysqli->query($sql); if(!$res) { printf('執行錯誤,錯誤代碼是%s,SQL語句是%s',$mysqli->error, $sql); exit; } //輸出影響的結果集,若是數據庫中的數值沒有變化,那麼就會輸出0 var_dump($mysqli->affected_rows); echo '執行成功'; ?>
注意:$mysqli->affected_rows的值爲0並不表明着執行失敗,而是對數據庫沒有影響,若是想獲取最新添加的自增加的ID,那麼用$mysqli->insert_id來獲取
七、mysqli的批量增刪改操做
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); $config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new mysqli($config['host'], $config['user'], $config['password'], $config['dbname'], $config['port']); if($mysqli->connect_errno) { die('鏈接錯誤'.$mysqli->connect_error); } $mysqli->set_charset('utf8'); $sql1 = 'UPDATE `student` SET `name` = "張飛" WHERE `studentid` = 13'; $sql2 = 'INSERT INTO `student` (`name`, `age`, `classid`) VALUES ("關羽", 19, 1)'; $sql3 = 'UPDATE `student` SET `age` = 20 WHERE `name` = "關羽"'; $sql = sprintf('%s;%s;%s',$sql1, $sql2, $sql3); if($mysqli->multi_query($sql)) { echo '執行成功'; } else { echo '執行失敗,錯誤碼是'.$mysqli->error; } ?>
八、mysqli 增刪改預處理
<?php header('content-type:text/html;charset=utf8'); ini_set('display_errors', true); $config = [ 'host' => 'localhost', 'user' => 'root', 'password' => 'phpcj', 'dbname' => 'learn', 'port' => 3306 ]; $mysqli = new mysqli($config['host'], $config['user'], $config['password'], $config['dbname'], $config['port']); if($mysqli->connect_errno) { die('鏈接錯誤'.$mysqli->connect_error); } $mysqli->set_charset('utf8'); //3. 編寫添加用戶的語句 ?佔位符號 $sql = "INSERT INTO `student` (`name`, `age`, `classid`) VALUES(?, ?, ?)"; //$sql = "UPDATE `student` SET `name` = ? WHERE studentid = ? "; //4.表明一個prepared語句 $pre_sql = $mysqli->prepare($sql); //5.給$pre_sql綁定參數 $name = "test"; $age = 40; $classid = 3; /* 功能: 給預處理語句的? 綁定參數 @param isd : 表示i=>int s=>string d=>double 小數 @param $id, $name, $money 傳入值 */ $pre_sql->bind_param('sii', $name, $age, $classid); if($pre_sql->execute()){ echo '<br> 執行成功!'; }else{ echo '<br> 執行失敗' . $mysqli->error; } ?>
注意:若是要再次用到預處理來添加數據,那麼只須要綁定值就能夠了即以上第5點如下再寫一次即可
九、mysqli的事務處理
<?php header('content-type:text/html;charset=utf-8'); // mysqli的事務控制 //鏈接數據庫... //演示使用mysqli完成dml $mySQLi = new MySQLi('localhost', 'root', '123', 'itbull', 3306); //判斷是否鏈接成功 //Returns the error code from last connect call //若是沒有錯誤,返回0,若是有錯誤,返回對應錯誤號 if($mySQLi->connect_errno){ //connect_error 屬性表示錯誤信息 die('鏈接錯誤,錯誤信息是' . $mySQLi->connect_error); }else{ echo '<br> 鏈接ok!'; } //2.設置字符集 $mySQLi->set_charset('utf8'); //3. 編寫sql $sql1 = "UPDATE `account` SET money = money - 1 WHERE id = 100"; $sql2 = "UPDAT `account` SET money = money + 1 WHERE id = 200"; //4. 開始事務 $mySQLi->begin_transaction(); $res1 = $mySQLi->query($sql1); $res2 = $mySQLi->query($sql2); if($res1 && $res2){ echo '<br> sql語句執行成功, 正式提交'; $mySQLi->commit(); }else{ echo '<br> sql語句有執行失敗的, 回滾'; $mySQLi->rollback(); }
2、PDO類的操做與使用
一、pdo擴展提供了三個類,分別是:PDO、PDOStatement、PDOException
PDO類鏈接數據庫,並對數據庫進行增刪改查操做
封裝個單例模式
<?php ini_set('display_errors', true); ERROR_REPORTING(E_ALL); final class DB { private static $db; private function __clone() {} private function __construct() { $config = parse_ini_file('./db.ini'); $dsn = sprintf('mysql:host=%s;dbname=%s;port=%d;charset=%s', $config['host'], $config['dbname'], $config['port'], $config['charset']); try{ self::$db = new PDO($dsn, $config['user'], $config['password']); }catch(PDOException $e) { exit($e->getMessage()); } } public static function getInstance(): PDO { if(!self::$db instanceof PDO) { new self(); } return self::$db; } } ?>
二、PDO返回的結果集分爲兩種狀況:第一種是增刪改,是經過PDO對象exec來實現的,返回的是受影響的記錄數, 第二種是查詢,經過PDO對象的query來實現的,返回的是查詢的結果集
三、PDO鏈接後針對以上的$pdo對象的屬性解析
errorcode() : 表示錯誤的code
errorinfo(): 表示錯誤的信息,返回的是一個數組,第一項是errorcode(), 第三項的錯誤具體信息
quote(): 對引號進行轉義以防止SQL注入
query(): 表示執行查詢語句, 當執行成功返回的是PDOStatement對象,若是執行失敗,那麼返回的是布爾值false
query 成功後返回PDOStatement對象裏面關乎查詢的方法有:
PDOStatement::fetch() 查詢一條記錄
PDOStatement::fetchAll() 查詢全部的記錄
注:以上兩個方法接收一個參數,一般使用PDO::FETCH_ASSOC返回關聯數組,PDO::FETCH_BOTH 返回關聯和索引數組 ,PDO::FETCH_NUM返回索引數組
<?php //在單例模式的基礎上 $db = DB::getInstance(); //查詢數據用query $querySql = sprintf('SELECT * FROM `user` WHERE `id` > %d', 0); $res = $db->query($querySql); var_dump($res->fetch(PDO::FETCH_ASSOC)); //輸出一個結果集 echo '<hr/>'; var_dump($res->fetchAll(PDO::FETCH_ASSOC)); //輸出所有的結果集 ?>
PDOStatement::fetchColumn() 接收一個數字型的參數,當有多條記錄時可不斷輸出指定列的數據,當沒有數據時返回bool(false);
<?php //在單例模式的基礎上 $db = DB::getInstance(); //查詢數據用query $querySql = sprintf('SELECT * FROM `user` WHERE `id` > %d', 0); $res = $db->query($querySql); //輸出結果集的全部查詢結果 var_dump($res->fetchColumn(1)); //輸出 「admin」 var_dump($res->fetchColumn(1)); //輸出 「aaa」 var_dump($res->fetchColumn(1)); //輸出 「bbb」 var_dump($res->fetchColumn(1)); //輸出 「ccc」 var_dump($res->fetchColumn(1)); //輸出 bool(false) ?>
exec(): 表示執行增刪改語句,返回的是受影響的記錄數
<?php //前提在上面單例模式的前提下進行調用 $db = DB::getInstance(); //插入數據用exec; //利用quote對引號進行轉義有利於防止sql注入 $insertSql = sprintf('INSERT INTO `user` (`user`, `pwd`) VALUE (%s, %1$.s), (%2$.s,%2$.s)', $db->quote('aaa'), $db->quote('bbb')); $res = $db->exec($insertSql); var_dump($res); //輸出 int(2); 若是執行錯誤,那麼返回bool(false) $updateSql = sprintf('UPDATE `user` SET `user` = %1$.s, `pwd` = %1$.s WHERE `user` = %2$.s', $db->quote('ccc'), $db->quote('aaa')); $res = $db->exec($updateSql); //輸出 int(1); 若是執行錯誤,那麼返回bool(false); ?>
prepare($sql): 表示pdo的預處理機制
A、利用預處理執行增刪改語句,下面以更新爲例
PDOStatement::bindValue 表示爲預處理語句綁定一個值
PDOStatement::execute() 表示執行預處理語句
PDOStatement::rowCount() 表示返回受影響的記錄數
<?php //在單例模式的基礎上 $db = DB::getInstance(); $sql = 'UPDATE `user` SET `user` = :user WHERE `id` = :id'; $res = $db->prepare($sql); $res->bindValue(':user', 'abc1', PDO::PARAM_STR); $res->bindValue(':id', 6, PDO::PARAM_INT); $res->execute(); //若是執行成功,那麼返回true,不然返回false; var_dump($res->rowCount()); //返回受影響的記錄數 ?>
B、預處理查詢語句
<?php //在單例模式的基礎上 $db = DB::getInstance(); $state = $db->prepare('SELECT * FROM `user` WHERE id > :id'); $state->bindValue(':id', 2, PDO::PARAM_INT); $state->execute(); $res = $state->fetchAll(PDO::FETCH_ASSOC); var_dump($res); //輸出結果集 ?>
PDOStatement::bindValue(':name', value, type) type有分紅PDO::PARAM_STR, PDO::PARAM_INT, PDO::PARAM_BOOL幾種(經常使用)
PDOStatement::bindParam(':name', value, type) type有分紅PDO::PARAM_STR, PDO::PARAM_INT, PDO::PARAM_BOOL幾種(經常使用)
bindValue 與 bindParam的區別:
一、bindParam是綁定一個參數到指定的變量名 bindValue則是把一個值綁定到一個參數
二、bindParam第二個參數有且只能是一個變量名, 不能是一個具體的值 bindValue既能夠綁定一個變量名,又能夠綁定一個值
三、不一樣於 PDOStatement::bindValue(),PDOStatement::bindParam()中的變量做爲引用被綁定,並只在 PDOStatement::execute() 被調用的時候才取其值
<?php //在單例模式的基礎上 $db = DB::getInstance(); $user = 'first'; $pwd = 'second'; $state = $db->prepare('INSERT INTO `user` (`user`, `pwd`) VALUES (:name, :pwd)'); //若是執行下面兩條語句,那麼存入數據庫的是 first 與 second $state->bindValue(':name', $user, PDO::PARAM_STR); $state->bindValue(':pwd', $pwd, PDO::PARAM_STR); //若是執行的是下面兩條語句,那麼存入數據庫的是 haha, check $state->bindParam(':name', $user, PDO::PARAM_STR); $state->bindParam(':pwd', $pwd, PDO::PARAM_STR); $user = 'haha'; $pwd = 'check'; $state->execute(); //返回的是bool(true) $res = $state->rowCount(); var_dump($res); //輸出結果集 int(1) ?>
PDOStatement::closeCursor():用於在查詢數據後關閉遊標和指針的(即初始化,便於下次查詢)
PDOStatement::errorCode(), PDOStatement::errorInfo(): 區別於pdo對象裏的方法,在statement裏面主要獲取預編譯時的錯誤信息和錯誤碼(執行以後才能得到錯誤信息)
lastInsertId(): 返回最新插入的記錄自增加ID
<?php //在單例模式的基礎上 $db = DB::getInstance(); $statement = $db->prepare('INSERT INTO `user` (`user`, `pwd`) VALUES (:name, :pwd)'); $statement->bindValue(':name', 'ricky'); $statement->bindValue(':pwd', '123456'); $statement->execute(); var_dump($statement->rowCount()); //輸出 int(1) var_dump($db->lastInsertId()); //輸出 string(1) "5" ?>
beginTransaction(): 開啓事務
commit(): 提交事務
rollBack(): 事務的回滾
<?php //在單例模式的基礎上 $db = DB::getInstance(); try { $sql = "UPDATE `user` SET `user`= :user WHERE `id`=:id"; $db->beginTransaction(); $exe1 = $db->prepare($sql); $exe2 = $db->prepare($sql); $exe1->bindValue(':user', 'this is first'); $exe1->bindValue(':id', 4, PDO::PARAM_INT); $exe2->bindValue(':user', 'this is second'); $exe2->bindValue(':id', 5, PDO::PARAM_INT); if($exe1->execute() && $exe2->execute()) { $db->commit(); } else { $db->rollBack(); } }catch(PDOException $e) { $db->rollBack(); exit($e->getMessage()); } ?>