當前位置: 首頁> 最新文章列表> 如何利用PDOStatement 根據條件安全刪除數據庫中的記錄?看完就會用

如何利用PDOStatement 根據條件安全刪除數據庫中的記錄?看完就會用

M66 2025-06-22

一、為什麼使用PDO 和預處理語句

在構造SQL 刪除語句時,很多開發者容易直接拼接字符串,比如這樣:

 $id = $_GET['id'];
$sql = "DELETE FROM users WHERE id = $id";

這種方式極易受到SQL 注入攻擊。例如,惡意用戶傳入1 OR 1=1 ,就會刪除整張表的內容。

使用PDO 的預處理語句,則可以徹底避免這個問題。它通過將SQL 和數據分離的方式,確保傳入的數據不會被解釋為SQL 語句的一部分。


二、使用PDO 刪除記錄的基本示例

下面是一個使用PDO 刪除用戶記錄的安全方式:

 <?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$username = 'root';
$password = 'your_password';

try {
    $pdo = new PDO($dsn, $username, $password);
    // 設置錯誤模式為異常
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // 預處理語句
    $stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");

    // 綁定參數並執行
    $id = 5; // 例如從表單或 URL 獲取的用戶ID
    $stmt->bindParam(':id', $id, PDO::PARAM_INT);

    $stmt->execute();

    if ($stmt->rowCount()) {
        echo "記錄已成功刪除。";
    } else {
        echo "未找到匹配的記錄。";
    }
} catch (PDOException $e) {
    echo "數據庫錯誤: " . $e->getMessage();
}
?>

在這個例子中,我們使用了:id佔位符,並通過bindParam綁定變量,確保數據類型一致性。


三、基於多個條件刪除記錄

有時刪除條件不止一個,例如刪除某個用戶在特定時間的登錄記錄:

 <?php
$stmt = $pdo->prepare("DELETE FROM login_logs WHERE user_id = :user_id AND login_time < :before_time");

$user_id = 3;
$before_time = '2024-01-01 00:00:00';

$stmt->bindParam(':user_id', $user_id, PDO::PARAM_INT);
$stmt->bindParam(':before_time', $before_time);

$stmt->execute();

四、動態條件的處理方式

如果刪除條件是動態生成的,比如來自前端的複選框批量刪除,可以這樣構造:

 <?php
$ids = [2, 5, 7]; // 來自表單或前端的 ID 列表

// 構造帶有佔位符的 SQL
$placeholders = implode(',', array_fill(0, count($ids), '?'));
$sql = "DELETE FROM users WHERE id IN ($placeholders)";
$stmt = $pdo->prepare($sql);

// 執行語句,綁定所有參數
$stmt->execute($ids);

這種方式利用了?佔位符和execute傳入數組的能力,既安全又靈活。


五、安全建議

  1. 永遠不要將用戶輸入直接拼接進SQL 中。

  2. 使用綁定參數時,指定數據類型(如PDO::PARAM_INT )可提高安全性與性能。

  3. 在刪除之前可以先進行SELECT 檢查,確認操作對像是否存在。

  4. 使用事務處理( beginTransaction() / commit() )以避免意外刪除。


六、結合接口刪除記錄(RESTful 接口示例)

如果你想基於HTTP 請求刪除某條記錄,例如通過接口https://m66.net/api/delete_user.php?id=9 ,你可以這樣寫:

 <?php
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['id'])) {
    $id = (int) $_GET['id'];

    $stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
    $stmt->bindParam(':id', $id, PDO::PARAM_INT);
    $stmt->execute();

    echo json_encode([
        'success' => true,
        'message' => '用戶刪除成功',
    ]);
} else {
    http_response_code(400);
    echo json_encode([
        'success' => false,
        'message' => '請求不合法',
    ]);
}
?>

接口設計中同樣必須重視輸入驗證和參數綁定,防止通過API 的方式被攻擊。