SQL削除ステートメントを作成する場合、多くの開発者は、このような次のような文字列を直接スプライスする傾向があります。
$id = $_GET['id'];
$sql = "DELETE FROM users WHERE id = $id";
この方法は、SQLインジェクション攻撃に対して非常に脆弱です。たとえば、悪意のあるユーザーが1または1 = 1に合格した場合、テーブル全体のコンテンツが削除されます。
この問題は、PDOの前処理ステートメントを使用して完全に回避できます。 SQLをデータから分離して、着信データがSQLステートメントの一部として解釈されないようにします。
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();
}
?>
この例では、 : BindParamを介してIDプレースホルダーとバインド変数を使用して、データ型の一貫性を確保します。
特定の時間にユーザーのログインレコードを削除するなど、複数の削除条件がある場合があります。
<?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);
このアプローチは、プレースホルダーの能力を活用し、実行してアレイに渡すことができます。これは、安全で柔軟なものです。
ユーザーの入力を直接SQLにスプライスしないでください。
バインディングパラメーターを使用する場合、データ型( PDO :: PARAM_INTなど)を指定すると、セキュリティとパフォーマンスが向上する可能性があります。
削除する前に、操作オブジェクトが存在するかどうかを確認するために選択チェックを実行できます。
偶発的な削除を避けるために、トランザクション処理( beginTransaction() / commive() )を使用します。
たとえば、インターフェイスhttps://m66.net/api/delete_user.php?id=9など、HTTPリクエストに基づいてレコードを削除する場合は、次のように書くことができます。
<?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を介した攻撃を防ぐために、入力検証とパラメーターバインディングも注意する必要があります。
関連タグ:
PDOStatement