站長資訊網
        最全最豐富的資訊網站

        通過PDO擴展與MySQL數據庫交互 實現增刪改查實現和數據庫事務

        通過PDO擴展與MySQL數據庫交互 實現增刪改查實現和數據庫事務

        相關學習推薦:mysql教程

        通過預處理語句進行增刪改查

        為什么使用預處理語句

        關于預處理語句我們在上篇教程中已經簡單介紹過,我們可以將其與視圖模板類比,所謂預處理語句就是預定義的 SQL 語句模板,其中的具體參數值通過占位符替代:

        INSERT INTO REGISTRY (name, value) VALUES (?, ?) INSERT INTO REGISTRY (name, value) VALUES (:name, :value)

        然后在后續真正要執行 SQL 語句之前,再通過特定 API 方法將具體參數值與對應占位符進行綁定和映射。就好比定義的視圖模板也是將變量通過特定占位符替代,然后真正渲染時將變量值傳遞進來填充和渲染一樣。

        為什么要費這番周折呢?直接用前面演示的 query 方法進行增刪改查操作它不香嗎?呃,那我們接下來來說說預處理語句的好處,或者說為什么要使用預處理語句進行數據庫交互,好處有二:

        • 首先,使用預處理語句提前定義的 SQL 模板只會解析一次,但可以通過傳遞不同的參數值執行多次,從而避免模板相同的 SQL 語句重復分析、編譯和優化,提高數據庫操作執行速度;
        • 其次,后期傳遞給預處理語句的參數值會被底層驅動進行處理,從而有效避免 SQL 注入攻擊。

        綜上,從性能和安全角度考慮,推薦使用預處理語句處理數據庫的增刪改查操作。

        增刪改查示例代碼

        接下來,我們基于 PDO 提供的預處理語句 API 實現 MySQL 數據庫的增刪改查操作,我們將通過面向對象的方式來實現:

        <?php class Post {     public $id;     public $title;     public $content;     public $created_at;      /**      * @var PDO      */     protected $pdo;      public function __construct(PDO $pdo = null)     {         if ($pdo != null) {             $this->pdo = $pdo;         }     }      public function insert($title, $content)     {         $sql = 'INSERT INTO `post` (title, content, created_at) VALUES (:title, :content, :created_at)';         try {             // 準備預處理語句             $stmt = $this->pdo->prepare($sql);             // 獲取當前時間對應的格式化字符串:2020-05-28 13:00:00             $datetime = date('Y-m-d H:i:s', time());             // 綁定參數值             $stmt->bindParam(':title', $title, PDO::PARAM_STR);             $stmt->bindParam(':content', $content, PDO::PARAM_STR);             $stmt->bindParam(':created_at', $datetime, PDO::PARAM_STR);             // 執行語句             $stmt->execute();             return $this->pdo->lastInsertId();  // 返回插入記錄對應ID         } catch (PDOException $e) {             printf("數據庫插入失敗: %sn", $e->getMessage());         }     }      public function select($id)     {         $sql = 'SELECT * FROM `post` WHERE id = ?';         try {             // 準備預處理語句             $stmt = $this->pdo->prepare($sql);             // 綁定參數值             $stmt->bindValue(1, $id, PDO::PARAM_INT);             // 執行語句             $stmt->execute();             return $stmt->fetchObject(self::class);  // 以對象方式返回結果集         } catch (PDOException $e) {             printf("數據庫查詢失敗: %sn", $e->getMessage());         }     }      public function selectAll()     {         $sql = 'SELECT * FROM `post` ORDER BY id DESC';         try {             // 準備預處理語句             $stmt = $this->pdo->prepare($sql);             // 執行語句             $stmt->execute();             return $stmt->fetchAll();  // 返回所有結果集         } catch (PDOException $e) {             printf("數據庫查詢失敗: %sn", $e->getMessage());         }     }      public function update($id)     {         $sql = 'UPDATE `post` SET created_at = :created_at WHERE id = :id';         try {             // 準備預處理語句             $stmt = $this->pdo->prepare($sql);             $datetime = date('Y-m-d H:i:s', time());             // 綁定參數值             $stmt->bindParam(':created_at', $datetime, PDO::PARAM_STR);             $stmt->bindValue(':id', $id, PDO::PARAM_INT);             // 執行語句             $stmt->execute();             return $stmt->rowCount();         } catch (PDOException $e) {             printf("數據庫更新失敗: %sn", $e->getMessage());         }     }      public function delete($id)     {         $sql = 'DELETE FROM `post` WHERE id = ?';         try {             // 準備預處理語句             $stmt = $this->pdo->prepare($sql);             // 綁定參數值             $stmt->bindValue(1, $id, PDO::PARAM_INT);             // 執行語句             $stmt->execute();             return $stmt->rowCount();         } catch (PDOException $e) {             printf("數據庫刪除失敗: %sn", $e->getMessage());         }     } }

        我們構建了一個 Post 類,然后在構造函數中初始化 $pdo 實例(從外部傳入),然后將基于預處理語句實現的增刪改查操作分解到對應的類方法中。整體邏輯非常簡單,以 insert 為例,首先通過 PDO 對象的 prepare 方法傳入 SQL 模板構建預處理語句,該方法返回 PDOStatement 對象,接下來,就是調用該對像的 bindParam 方法綁定具體參數值,該方法的第一個參數是占位符,第二個參數是參數值,第三個參數是值類型(對應的常量可以在 PDO 預定義常量中查詢),綁定好參數后,就可以調用 PDOStatement 對象的 execute 方法執行預處理語句了。

        對于插入操作,可以通過 PDO 對象上的 lastInsertId 方法返回插入記錄的主鍵 ID,對于更新和刪除方法,可以通過 PDOStatement 對象上的 rowCount 方法返回受影響行數表示是否操作成功。對于查詢操作,可以通過 PDOStatement 對象的 fetch 方法返回單條記錄,也可以通過 fetchObject 方法返回映射到指定類后的對象實例(也是單條記錄),對于多個結果,可以通過 fetchAll 方法返回。

        需要注意的是,在聲明預處理語句的時候,可以通過 ? 占位符,也可以通過 :name 這種可讀性更好的占位符,然后在綁定參數時,既可以通過 bindValue 也可以通過 bindParam 方法,兩者傳遞參數一樣,只是對于 ? 占位符,需要通過數值序號建立與 SQL 模板的映射(從 1 開始)。

        結合代碼和 PHP 官方文檔理解上面的代碼并不困難,接下來,我們來編寫測試代碼:

        // 初始化 PDO 連接實例 $dsn = 'mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8mb4'; $user = 'root'; $pass = 'root'; try {     $pdo = new PDO($dsn, $user, $pass); } catch (PDOException $e) {     printf("數據庫連接失敗: %sn", $e->getMessage()); }  // 測試代碼 $post = new Post($pdo); // insert $title = '這是一篇測試文章'; $content = '測試內容: 今天天氣不錯'; $id = $post->insert($title, $content); echo '文章插入成功: ' . $id . '<br>'; // select $item = $post->select($id); echo '<pre>'; print_r($item); // update $affected = $post->update($id); echo '受影響的行數: ' . $affected . '<br>'; // delete $affected = $post->delete($id); echo '受影響的行數: ' . $affected . '<br>'; // selectAll $items = $post->selectAll(); print_r($items);

        初始化一個 PDO 對象實例傳入 Post 構造函數,然后依次調用 Post 對象的增刪改查方法。在瀏覽器中訪問,打印結果如下:

        通過PDO擴展與MySQL數據庫交互 實現增刪改查實現和數據庫事務

        我們可以看到 fetchAll 方法默認返回的結果集數組中既包含索引映射,又包含字段名映射,這可以通過設置獲取模式來解決,比如要返回 Post 對象數組,可以這么做:

        return $stmt->fetchAll(PDO::FETCH_CLASS, self::class);

        這樣,返回的結果就是這樣的了:

        通過PDO擴展與MySQL數據庫交互 實現增刪改查實現和數據庫事務

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲精品成人无限看| 国产亚洲一区二区精品| 成人区人妻精品一区二区不卡网站| 97精品人妻一区二区三区香蕉 | 久久精品18| 国产偷亚洲偷欧美偷精品| 亚洲精品无码国产| 精品欧美激情在线看| 四虎精品影院永久在线播放| 国产午夜福利精品久久2021| 日韩精品免费一线在线观看| 国产在线观看一区精品 | 国产精品大白天新婚身材| 无码精品国产VA在线观看| 美女岳肉太深了使劲国产精品亚洲专一区二区三区 | 国产福利精品视频自拍 | 精品人妻大屁股白浆无码| 亚洲日韩中文在线精品第一| 日韩亚洲精品福利 | 精品国产免费一区二区三区| 亚洲第一精品在线视频| 国产精品一区二区不卡| 成人午夜视频精品一区| 国产精品污WWW在线观看| 久久久久亚洲精品无码蜜桃| 最新精品露脸国产在线 | 永久无码精品三区在线4| 下载天堂国产AV成人无码精品网站| 国产精品久久久久久久久久免费| 911亚洲精品国内自产| 久久精品国产亚洲麻豆| 日韩麻豆国产精品欧美| 91久久精品国产免费直播| 国产成人亚洲精品91专区手机| www夜片内射视频日韩精品成人| 98精品国产自产在线XXXX| 国产A∨国片精品一区二区 | 亚洲AV永久青草无码精品| 人人妻人人澡人人爽人人精品电影| 色欲久久久天天天综合网精品| 久久久国产乱子伦精品作者|