搜尋
首頁後端開發PHP問題一分鐘帶你了解PHP中的預處理語句及事務

這篇文章跟大家介紹一下PHP中的預處理語句及事務。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

一分鐘帶你了解PHP中的預處理語句及事務

PHP中的PDO操作學習(二)預處理語句及事務

今天這篇文章,我們來簡單的學習PDO 中的預處理語句以及交易的使用,它們都是在PDO 物件下的操作,而且並不復雜,簡單的應用都能輕鬆實現。只不過大部分情況下,大家都在使用框架,手寫的機會非常少。

預處理語句功能

預處理語句就是準備好一個要執行的語句,然後回傳一個 PDOStatement 物件。一般我們會使用 PDOStatement 物件的 execute() 方法來執行這條語句。為什麼叫預處理呢?因為它可以讓我們多次呼叫這條語句,並且可以透過佔位符來取代語句中的欄位條件。相較於直接使用 PDO 物件的 query() 或 exec() 來說,預處理的效率更高,它可以讓客戶端/伺服器快取查詢和元資訊。當然,更重要的一點是,佔位符的應用可以有效的防止基本的SQL 注入攻擊,我們不需要手動地為SQL 語句加上引號,直接讓預處理來解決這個問題,相信這一點是大家都學習過的知識,也是我們在面試時最常見到的問題之一。

// 使用 :name 形式创建一个只进游标的 PDOStatement 对象
$stmt = $pdo->prepare("select * from zyblog_test_user where username = :username", [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);

var_dump($stmt);
// object(PDOStatement)#2 (1) {
//     ["queryString"]=>
//     string(57) "select * from zyblog_test_user where username = :username"
//   }

$stmt->execute([':username' => 'aaa']);
$aUser = $stmt->fetchAll();

$stmt->execute([':username' => 'bbb']);
$bUser = $stmt->fetchAll();

var_dump($aUser);
// array(1) {
//     [0]=>
//     array(8) {
//       ["id"]=>
//       string(1) "1"
//       [0]=>
//       string(1) "1"
//       ["username"]=>
//       string(3) "aaa"
//       ……

var_dump($bUser);
// array(1) {
//     [0]=>
//     array(8) {
//       ["id"]=>
//       string(1) "2"
//       [0]=>
//       string(1) "2"
//       ["username"]=>
//       string(3) "bbb"
//       ……

prepare() 方法的第一個參數就是我們需要執行的SQL 語句,在這段程式碼中,我們使用的是:xxx 形式的佔位符,所以在呼叫prepare() 方法返回的PDOStatement 物件的execute() 方法時,我們需要指定佔位符的值。在程式碼中,我們使用這一條 SQL 語句,透過取代不同的佔位符內容,實現了兩次查詢。

prepare() 方法的第二個參數是為傳回的 PDOStatement 物件設定的屬性。常見用法是:設定 PDO::ATTR_CURSOR 為 PDO::CURSOR_SCROLL,將會得到可捲動的遊標。 

某些駕駛有驅動級的選項,在 prepare 時就設定。 PDO::ATTR_CURSOR 是設定資料庫遊標的類型,而 PDO::CURSOR_FWDONLY 的意思是建立一個只進遊標的 PDOStatement 物件。此為預設的遊標選項,因為此遊標最快且是 PHP 中最常用的資料存取模式。關於資料庫遊標的知識大家可以自行查閱相關的內容。

此外,PDOStatement 還可以透過 bindParam() 方法來綁定佔位符數據,我們將在後面學習 PDOStatement 物件相關的文章中繼續學習。

接下來,我們再看一下使用 ? 號佔位符來實現查詢,? 號佔位符在綁定的時候是以下標形式進行綁定的。

// 使用 ? 形式创建一个只进游标的 PDOStatement 对象
$stmt = $pdo->prepare("select * from zyblog_test_user where username = ?", [PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY]);

$stmt->execute(['aaa']);
$aUser = $stmt->fetchAll();

var_dump($aUser);
// array(1) {
//     [0]=>
//     array(8) {
//       ["id"]=>
//       string(1) "1"
//       [0]=>
//       string(1) "1"
//       ["username"]=>
//       string(3) "aaa"
//       ……

當然,這種預編譯語句不只限於查詢語句,增、刪、改都是可以的,也都是支援佔位符的。在 PHP中操作資料庫的預處理語句 這篇文章中有詳細的範例。

事務能力

關於事務想必大家也都有一定的了解,所以在這裡也不介紹具體的概念了,我們只看看在PDO 中事務是如何實現的。首先,我們先看下在沒有事務的情況下會發生什麼事。

$pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)"); // 成功插入

$pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)"); // 报错停止整个PHP脚本执行
// Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.tran_innodb2' doesn't exist

假設這兩個表需要同時更新,但第二個語句報錯了。在沒有事務的情況下,我們第一個資料是會正常插入成功的,這並不是我們需要的結果。在這時,就需要事務能力的幫助,讓我們能夠讓兩個表格要麼同時成功,要麼同時失敗。

try {
    // 开始事务
    $pdo->beginTransaction();

    $pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)");
    $pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)"); // 不存在的表

    // 提交事务
    $pdo->commit();
} catch (Exception $e) {
    // 回滚事务
    $pdo->rollBack();
    // 输出报错信息
    echo "Failed: " . $e->getMessage(), PHP_EOL;
    // Failed: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'blog_test.tran_innodb2' doesn't exist
}

首先就是beginTransaction() 方法,它是用來關閉資料庫的自動提交,並啟動一個事務,在這個方法之後,只有遇到commit() 或者rollBack() 方法後才會關閉這個事務。

commit() 方法就是在操作過程中沒有出現意外的話,就將在 beginTransaction() 之後的所有資料操作一起打包提交。

rollBack() 是回滾數據,當beginTransaction() 之後的某語句或程式碼出現問題時,回滾之前的資料操作,保證beginTransaction() 之後的所有語句要麼都成功,要麼都失敗。

就是這樣三個簡單的函數,就為我們完成了整個事務操作。關於事務的深入學習我們將在將來深入研究 MySQL 時再進行探討。這裡我們需要注意的是,PDO 物件最好指定錯誤模式為拋出異常,如果不指定錯誤模式的話,事務中出現的錯誤也不會直接報錯,而是返回錯誤碼,我們需要透過錯誤碼來確定是否提交或回滾。這樣遠沒有異常機制來的簡潔直覺。

总结

我们简单的梳理并学习了一下 PDO 中的预处理和事务相关的知识,接下来就要进入 PDOStatement 对象相关内容的学习。PDOStatement 对象就是 PDO 的预处理对象,也就是在日常开发中我们会接触到的最多的数据操作对象。这块可是重点内容,大家可不能松懈了哦!

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP%E4%B8%AD%E7%9A%84PDO%E6%93%8D%E4%BD%9C%E5%AD%A6%E4%B9%A0%EF%BC%88%E4%BA%8C%EF%BC%89%E9%A2%84%E5%A4%84%E7%90%86%E8%AF%AD%E5%8F%A5%E5%8F%8A%E4%BA%8B%E5%8A%A1.php

推荐学习:php视频教程

以上是一分鐘帶你了解PHP中的預處理語句及事務的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具