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 () / commit () )를 사용하십시오.
예를 들어 인터페이스 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