PHP 폼 재전송(새로고침) 문제 해결하기

프리터코더·2025년 5월 28일
0

php 문제 해결

목록 보기
45/79

사용자가 폼 제출 후 새로고침을 누르면 데이터가 중복 전송되는 문제는 웹 개발에서 자주 발생합니다. 이를 효과적으로 해결하는 방법들을 알아보겠습니다.

1. PRG 패턴 (Post-Redirect-Get)

문제: POST 후 새로고침 시 폼이 재전송됨

해결책: POST 처리 후 GET 페이지로 리다이렉트

if ($_POST) {
    // 폼 데이터 처리
    $name = $_POST['name'];
    $email = $_POST['email'];
    
    // 데이터베이스에 저장
    saveUser($name, $email);
    
    // 리다이렉트로 재전송 방지
    header('Location: success.php');
    exit;
}

2. 토큰 기반 중복 방지

문제: 의도적인 중복 제출 방지 필요

해결책: CSRF 토큰을 활용한 일회성 토큰 시스템

session_start();

// 폼 표시 시 토큰 생성
if (!isset($_SESSION['form_token'])) {
    $_SESSION['form_token'] = bin2hex(random_bytes(32));
}

// 폼 처리
if ($_POST && isset($_POST['token'])) {
    if ($_POST['token'] === $_SESSION['form_token']) {
        // 정상 처리
        processForm($_POST);
        
        // 토큰 삭제로 재사용 방지
        unset($_SESSION['form_token']);
        
        header('Location: success.php');
        exit;
    }
}
<form method="POST">
    <input type="hidden" name="token" value="<?= $_SESSION['form_token'] ?>">
    <input type="text" name="name" required>
    <button type="submit">전송</button>
</form>

3. 세션 기반 중복 체크

문제: 같은 데이터의 연속 제출 방지

해결책: 마지막 제출 데이터를 세션에 저장하여 비교

session_start();

if ($_POST) {
    $current_data = serialize($_POST);
    
    // 이전 제출과 동일한지 확인
    if (isset($_SESSION['last_submit']) && $_SESSION['last_submit'] === $current_data) {
        // 중복 제출 감지
        header('Location: already_submitted.php');
        exit;
    }
    
    // 데이터 처리
    processForm($_POST);
    
    // 현재 제출 데이터 저장
    $_SESSION['last_submit'] = $current_data;
    
    header('Location: success.php');
    exit;
}

4. JavaScript 버튼 비활성화

문제: 사용자가 여러 번 클릭하는 경우

해결책: 제출 후 버튼 비활성화

<form method="POST" onsubmit="disableSubmit()">
    <input type="text" name="name" required>
    <button type="submit" id="submitBtn">전송</button>
</form>

<script>
function disableSubmit() {
    document.getElementById('submitBtn').disabled = true;
    document.getElementById('submitBtn').value = '처리중...';
    return true;
}
</script>

5. 데이터베이스 유니크 제약조건 활용

문제: 중복 데이터가 DB에 저장되는 경우

해결책: 유니크 키와 예외 처리 조합

try {
    $stmt = $pdo->prepare("INSERT INTO users (email, name) VALUES (?, ?)");
    $stmt->execute([$email, $name]);
    
    header('Location: success.php');
    exit;
    
} catch (PDOException $e) {
    if ($e->getCode() == 23000) { // 중복 키 에러
        header('Location: duplicate_error.php');
        exit;
    }
    throw $e;
}
profile
일용직 개발자. freetercoder@gmail.com

0개의 댓글