對(duì)于 MySQLi 來說帘腹,事務(wù)和預(yù)處理語(yǔ)句當(dāng)然是它之所以能夠淘汰 MySQL(原始) 擴(kuò)展的資本。我們之前也已經(jīng)學(xué)習(xí)過了 PDO 中關(guān)于事務(wù)和預(yù)處理語(yǔ)句相關(guān)的內(nèi)容。所以在這里,我們就不再多講理論方面的東西了,直接上代碼來看看 MySQLi 中這兩大特性與 PDO 在使用上的區(qū)別哲银。
事務(wù)處理
首先,我們還是要讓 MySQLi 對(duì)于錯(cuò)誤的語(yǔ)句也報(bào)出異常來呻惕。關(guān)于這個(gè)功能就和 PDO 很不一樣了荆责。在 PDO 中,我們直接指定連接的報(bào)錯(cuò)屬性就可以了亚脆。而在 MySQLi 中做院,我們則需要指定 MySQLi_Driver 對(duì)象中的報(bào)錯(cuò)屬性為拋出異常,很明顯,MySQLi_Driver 就是 MySQLi 的驅(qū)動(dòng)對(duì)象键耕。
// 使用異常處理錯(cuò)誤情況
$driver = new mysqli_driver();
$driver->report_mode = MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT;
這樣就指定了在使用 MySQLi 擴(kuò)展時(shí)寺滚,所有的錯(cuò)誤信息都會(huì)作為異常拋出。
接下來的內(nèi)容屈雄,其實(shí)就和 PDO 很相似了村视。
try {
// 開始事務(wù)
$mysqli->begin_transaction();
$mysqli->query("insert into tran_innodb (name, age) values ('Joe', 12)");
$mysqli->query("insert into tran_innodb2 (name, age) values ('Joe', 12)"); // 不存在的表
// 提交事務(wù)
$mysqli->commit();
} catch (Exception $e) {
// 回滾事務(wù)
$mysqli->rollback();
var_dump($e->getMessage());
// string(44) "Table 'blog_test.tran_innodb2' doesn't exist"
}
我們同樣是使用一個(gè) begin_transaction() 來啟動(dòng)事務(wù)。然后通過 commint() 方法來提交事務(wù)酒奶。在這段測(cè)試代碼中蚁孔,第二條 SQL 語(yǔ)句是會(huì)報(bào)錯(cuò)的,于是進(jìn)入了 catch 中惋嚎,使用 rollback() 來回滾事務(wù)杠氢。
預(yù)處理語(yǔ)句
總體來說,事務(wù)的處理和 PDO 的區(qū)別不大另伍,但是預(yù)處理語(yǔ)句和 PDO 中的使用的區(qū)別就有一些了鼻百。首先是我們的 MySQLi 中的占位符只有 ? 問號(hào)占位。另外也只有 bind_param() 沒有類似于 PDO 中的 bindValue() 方法质况。
$stmt = $mysqli->prepare("select * from zyblog_test_user where username = ?");
$username = 'aaa';
$stmt->bind_param("s", $username); // 綁定參數(shù)
$stmt->execute(); // 執(zhí)行語(yǔ)句
$aUser = $stmt->fetch(); // 獲取mysqli_result結(jié)果集對(duì)象
$username='bbb';
$stmt->bind_param('s', $username);
$stmt->execute();
$bUser = $stmt->fetch();
var_dump($aUser);
// array(4) {
// ["id"]=>
// int(1)
// ["username"]=>
// string(3) "aaa"
// ["password"]=>
// string(3) "aaa"
// ["salt"]=>
// string(3) "aaa"
// }
var_dump($bUser);
// array(4) {
// ["id"]=>
// int(2)
// ["username"]=>
// string(3) "bbb"
// ["password"]=>
// string(3) "bbb"
// ["salt"]=>
// string(3) "123"
// }
從代碼中可以看出,bind_param() 方法的使用也和 PDO 有很大的不同玻靡。它不需要下標(biāo)结榄,而是給了一個(gè) s 參數(shù)。這個(gè)參數(shù)表明的是綁定數(shù)據(jù)的類型囤捻,s 就是字符串類型臼朗。其它的類型我們?cè)趯W(xué)習(xí) MySQLi_STMT 相關(guān)的內(nèi)容時(shí)再深入的了解。
總結(jié)
其實(shí)從代碼層面來說蝎土,大部分的內(nèi)容都是和 PDO 非常相似的视哑,只是有些參數(shù)的不同而已。對(duì)于我們來說誊涯,還是多以學(xué)習(xí)了解為主挡毅,在自己封裝或者使用某些以 MySQLi 為底層數(shù)據(jù)庫(kù)操作的框架時(shí)不至于暈頭轉(zhuǎn)向。
測(cè)試代碼:
參考文檔:
https://www.php.net/manual/zh/book.mysqli.php
各自媒體平臺(tái)均可搜索【硬核項(xiàng)目經(jīng)理】