PHP - Post-Redirect-Get (PRG)
안녕하세요, 열망하는 프로그래머 여러분! 오늘 우리는 중요한 웹 개발 패턴인 Post-Redirect-Get, 짧게는 PRG라고 부르는 것에 대해 깊이 다룰 것입니다. 프로그래밍 초보자라면 걱정하지 마세요; 단계별로 이 개념을 안내해 드릴게요. 수년 동안 수많은 학생들에게 가르쳐온 경험을 바탕으로 말이죠. 커피 한 잔 (또는 당신의 좋아하는 음료)을 들고, 이 흥미로운 여정에 함께 뛰어들어 보세요!
What is Post-Redirect-Get (PRG)? (Post-Redirect-Get은 무엇인가요?)
온라인으로 피자를 주문하는 양식을 작성하고 있을 때를 상상해 보세요. 제출을 클릭하고 나서... 아이고! 실수로 페이지를 새로 고침 했습니다. 갑자기 피자 두 개를 주문하게 되었어요! 이런 문제를 해결해주는 것이 PRG 패턴입니다.
PRG는 사용자가 양식을 제출한 후 페이지를 새로 고침할 때 중복 양식 제출을 방지하는 웹 개발 디자인 패턴입니다. 웹 애플리케이션에서 데이터가 원활하게 흐르고 우연히 중복되지 않도록 하는 교통警察 같은 역할을 합니다.
How PRG Works (PRG은 어떻게 작동하나요?)
- 사용자가 POST 요청을 사용하여 양식을 제출합니다.
- 서버는 양식 데이터를 처리합니다.
- 서버는 직접 응답을 보내지 않고 대신 리디렉션을 보냅니다 (보통 성공 페이지로).
- 사용자의 브라우저는 리디렉션을 따라 GET 요청을 보냅니다.
- 서버는 GET 요청에 대한 응답으로 최종 페이지를 보냅니다.
이제 코드 예제를 통해 이를 실제로 보겠습니다!
Example 1: A Simple PRG Implementation (간단한 PRG 구현 예제)
PHP에서 PRG가 어떻게 작동하는지 기본적인 예제로 시작해 보겠습니다. 사용자가 좋아하는 색상을 제출할 수 있는 간단한 양식을 만들어 보겠습니다.
Step 1: The HTML Form (form.php) (HTML 양식)
<!DOCTYPE html>
<html>
<head>
<title>Favorite Color Form</title>
</head>
<body>
<h1>What's Your Favorite Color?</h1>
<form action="process.php" method="post">
<input type="text" name="color" required>
<input type="submit" value="Submit">
</form>
</body>
</html>
이 양식은 제출 시 process.php
로 POST 요청을 보냅니다.
Step 2: Processing the Form (process.php) (양식 처리)
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$color = $_POST['color'];
// 색상을 세션에 저장
$_SESSION['favorite_color'] = $color;
// 결과 페이지로 리디렉션
header('Location: result.php');
exit;
} else {
// 누군가 이 페이지를 직접 접근하려고 시도하면 양식으로 리디렉션
header('Location: form.php');
exit;
}
이 스크립트는 다음과 같은 작업을 수행합니다:
- 세션을 시작하여 페이지 간 데이터를 저장합니다.
- 요청 메서드가 POST인지 확인합니다.
- POST 요청이면 제출된 색상을 세션에 저장합니다.
- 사용자를
result.php
로 리디렉션합니다. - 직접 접근 시 양식 페이지로 리디렉션합니다.
Step 3: Displaying the Result (result.php) (결과 표시)
<?php
session_start();
if (isset($_SESSION['favorite_color'])) {
$color = $_SESSION['favorite_color'];
// 세션 변수를 지우기 위해 데이터를 지운 후
unset($_SESSION['favorite_color']);
} else {
$color = 'No color submitted';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Your Favorite Color</title>
</head>
<body>
<h1>Your Favorite Color</h1>
<p>You said your favorite color is: <?php echo htmlspecialchars($color); ?></p>
<a href="form.php">Submit another color</a>
</body>
</html>
이 확인 페이지는 다음과 같은 작업을 수행합니다:
- 세션을 다시 시작하여 저장된 데이터에 접근합니다.
- 좋아하는 색상이 세션에 저장되어 있는지 확인합니다.
- 저장되어 있으면 표시하고 세션 변수를 지웁니다.
- 저장되어 있지 않으면 기본 메시지를 표시합니다.
이제 사용자가 결과 페이지를 새로 고침해도 양식 데이터를 다시 제출하지 않습니다. 멋지죠?
Example 2: PRG with Database Interaction (데이터베이스와 상호작용하는 PRG)
이제 우리의 예제를 한 단계 더 발전시키고, 피자 주문 시스템을 운영하고 있다고 상상해 보겠습니다. 주문을 데이터베이스에 저장하고 PRG를 사용하여 중복 주문을 방지하겠습니다.
Step 1: The Order Form (order_form.php) (주문 양식)
<!DOCTYPE html>
<html>
<head>
<title>Pizza Order Form</title>
</head>
<body>
<h1>Order Your Pizza</h1>
<form action="process_order.php" method="post">
<label for="pizza_type">Pizza Type:</label>
<select name="pizza_type" id="pizza_type" required>
<option value="margherita">Margherita</option>
<option value="pepperoni">Pepperoni</option>
<option value="veggie">Veggie</option>
</select>
<br><br>
<label for="size">Size:</label>
<select name="size" id="size" required>
<option value="small">Small</option>
<option value="medium">Medium</option>
<option value="large">Large</option>
</select>
<br><br>
<input type="submit" value="Place Order">
</form>
</body>
</html>
Step 2: Processing the Order (process_order.php) (주문 처리)
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pizza_type = $_POST['pizza_type'];
$size = $_POST['size'];
// 실제 애플리케이션에서는 이 입력을 정리하고 검증해야 합니다
// 데이터베이스에 연결 (이를 별도 파일에 저장하는 것이 일반적입니다)
$db = new PDO('mysql:host=localhost;dbname=pizza_shop', 'username', 'password');
// 주문을 추가
$stmt = $db->prepare("INSERT INTO orders (pizza_type, size) VALUES (?, ?)");
$stmt->execute([$pizza_type, $size]);
// 주문 ID를 가져옵니다
$order_id = $db->lastInsertId();
// 주문 ID를 세션에 저장
$_SESSION['last_order_id'] = $order_id;
// 확인 페이지로 리디렉션
header('Location: order_confirmation.php');
exit;
} else {
// 누군가 이 페이지를 직접 접근하려고 시도하면 양식으로 리디렉션
header('Location: order_form.php');
exit;
}
이 스크립트는 다음과 같은 작업을 수행합니다:
- 양식 데이터를 처리합니다.
- 데이터베이스에 주문을 추가합니다.
- 주문 ID를 세션에 저장합니다.
- 사용자를 확인 페이지로 리디렉션합니다.
- 직접 접근 시 양식 페이지로 리디렉션합니다.
Step 3: Order Confirmation (order_confirmation.php) (주문 확인)
<?php
session_start();
if (isset($_SESSION['last_order_id'])) {
$order_id = $_SESSION['last_order_id'];
// 세션 변수를 지우기 위해 데이터를 지운 후
unset($_SESSION['last_order_id']);
// 실제 애플리케이션에서는 데이터베이스에서 주문 상세 정보를 가져옵니다
// 이 예제에서는 주문 ID만 표시합니다
$message = "Your order (ID: $order_id) has been placed successfully!";
} else {
$message = "No recent order found. Please place a new order.";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Order Confirmation</title>
</head>
<body>
<h1>Order Confirmation</h1>
<p><?php echo htmlspecialchars($message); ?></p>
<a href="order_form.php">Place another order</a>
</body>
</html>
이 확인 페이지는 다음과 같은 작업을 수행합니다:
- 세션에서 주문 ID를 가져옵니다.
- 확인 메시지를 표시하고 세션 변수를 지웁니다.
- 최근 주문이 없으면 기본 메시지를 표시합니다.
이제 사용자가 확인 페이지를 새로 고침해도 중복 주문이 발생하지 않습니다.
Why PRG is Important (PRG의 중요성)
- Prevents Duplicate Submissions: 사용자가 확인 페이지를 새로 고침하면 우연히 주문을 다시 제출하지 않습니다.
- Improves User Experience: 사용자는 깨끗한 URL을 브라우저의 주소 표시줄에서 볼 수 있으며, 양식 데이터가 긴 문자열로 표시되지 않습니다.
- Follows REST Principles: GET 요청은 데이터를检索하는 데 사용되고, POST 요청은 데이터를 제출하는 데 사용됩니다.
Common PRG Methods (PRG에서 사용되는 일반 방법)
다음은 PRG 패턴에서 사용되는 일반적인 메서드 표입니다:
Method | Description |
---|---|
$_SERVER['REQUEST_METHOD'] |
HTTP 요청 메서드 (GET, POST 등)를 확인합니다 |
header('Location: ...') |
브라우저로 리디렉션 헤더를 보냅니다 |
exit |
리디렉션 후 추가 코드가 실행되지 않도록 합니다 |
session_start() |
새로운 세션을 시작하거나 기존 세션을 계속합니다 |
$_SESSION |
세션 데이터를 저장하고检索합니다 |
isset() |
변수가 설정되어 있고 NULL이 아닌지 확인합니다 |
unset() |
지정된 변수를 파괴합니다 |
젊은 파다와안, PRG 패턴은 웹 개발에서 힘을 사용하는 것처럼입니다. 중복 양식 제출의 어둠 쪽을 방지하여 애플리케이션에 균형을 가져옵니다. 코드가 당신과 함께 하길 바랍니다!
결론적으로, Post-Redirect-Get 패턴은 웹 개발 도구箱에서 강력한 도구입니다. 우연한 중복 제출을 방지하여 더 견고하고 사용자 친화적인 애플리케이션을 만들어줍니다. PHP와 웹 개발을 계속하면서 PRG가 당신을 구원할 많은 상황을 만날 것입니다. 계속 연습하고, 호기심을 잃지 마세요, 행복한 코딩을 기원합니다!
Credits: Image by storyset