시작 오늘 분석할 코드
입력 → 확인 → 완료의 3단계 폼 패턴이다. 확인 페이지(confirm.php)에서 내용을 보여주고, 최종 확인 버튼을 눌러야 view.php로 넘어간다. 데이터는 hidden 필드를 통해 각 단계로 이어진다.
form.html
입력
→
confirm.php
확인
→
view.php
완료
form.html — 입력 화면 (핵심: hidden user_id)
<FORM name="form1" method="post" action="confirm.php"> 이름: <INPUT type="text" name="onamae"><BR> 본문: <TEXTAREA name="honbun" cols="30" rows="5"></TEXTAREA><BR> <INPUT type="submit" value="송신"> <INPUT type="hidden" name="user_id" value="0001"> <!-- 화면에 안 보임 --> </FORM>
confirm.php — 확인 화면 (데이터 재전달)
확인화면 <FORM name="form1" method="post" action="view.php"> <?php print "이름:"; print $_POST["onamae"]; print "<BR><BR>본문 :<BR>"; print nl2br($_POST["honbun"]); ?> <INPUT type="submit" value="확인"> <INPUT type="hidden" name="onamae" value="<?=$_POST["onamae"]?>"> <INPUT type="hidden" name="honbun" value="<?=$_POST["honbun"]?>"> <INPUT type="hidden" name="user_id" value="<?=$_POST["user_id"]?>"> </FORM>
view.php — 최종 완료 화면
<?php print $_POST["onamae"]."님으로부터의 메시지"; print "<BR><BR>본문 :<BR>"; print nl2br($_POST["honbun"]); ?>
용어 용어 정리
type="hidden"화면에 보이지 않지만 FORM과 함께 전송되는 INPUT
confirm 페이지입력 내용을 보여주며 "맞으면 확인, 틀리면 수정" 선택하는 중간 화면
<?= ?>PHP 단축 출력 태그 — <?php echo ... ?> 의 축약형
데이터 릴레이한 페이지에서 받은 데이터를 hidden으로 다음 페이지로 전달하는 패턴
user_id사용자에게 보이지 않도록 숨긴 식별 정보 — hidden으로 전달
3단계 폼입력(form) → 확인(confirm) → 완료(view) 패턴 — 실수 방지용
short_open_tagphp.ini 설정 — On이면 <?= ?> 사용 가능
$_SESSION서버 측 저장 — hidden보다 안전한 데이터 전달 수단
1 왜 확인 화면이 필요한가?
2단계 vs 3단계 폼
2단계 폼(form → view)은 한 번 "송신"을 누르면 바로 처리된다. 실수로 잘못된 내용을 입력해도 되돌릴 방법이 없다. 3단계 폼은 중간에 확인 화면을 삽입해 사용자가 내용을 검토하고 최종 승인하도록 한다.
회원가입, 결제, 게시글 등록처럼 한 번 제출하면 돌이키기 어려운 작업에 이 패턴이 많이 쓰인다.
※ UX 관점에서도 확인 화면은 사용자의 실수를 줄여주고, 마지막으로 검토할 기회를 제공한다. 특히 결제, 삭제, 대량 변경 같은 고위험 작업에 필수다.
2 INPUT type="hidden" — 보이지 않는 데이터 운반체
hidden 필드는 왜 쓰는가?
POST 요청은 그 페이지에서만 살아있다. confirm.php에서 받은 $_POST 데이터는 view.php로 자동으로 넘어가지 않는다. 그래서 confirm.php 안의 FORM에 hidden INPUT을 넣어 데이터를 다시 담아 view.php로 재전송한다.
// confirm.php가 받은 $_POST 데이터를 view.php로 넘기는 방법: <INPUT type="hidden" name="onamae" value="<?=$_POST["onamae"]?>"> ↑ form.html에서 온 값을 hidden에 담아 → 다음 단계(view.php)로 재전송
※ hidden은 브라우저 화면에는 안 보이지만, 개발자도구(F12)에서 HTML 소스를 보면 그대로 노출된다. 비밀번호 같은 민감 정보는 hidden에 담으면 안 된다.
hidden 필드가 없으면 어떻게 되는가?
confirm.php에서 hidden을 빠뜨리고 view.php에서 $_POST["onamae"]에 접근하면 "Undefined index" 경고가 뜨고 빈 값이 나온다. 각 POST 요청은 독립적으로 처리되기 때문에, 이전 단계의 데이터를 명시적으로 다음 단계에 전달해야 한다. PHP 세션을 쓰지 않는 한 hidden 필드가 유일한 방법이다.
3 <?= ?> — PHP 단축 출력 태그
왜 print 대신 <?= 를 쓰는가?
HTML 속성값 안에 PHP 변수를 끼워 넣을 때는 <?php print ... ?>보다 <?= ... ?> 단축형이 훨씬 읽기 쉽다.
// 긴 형태 value="<?php print $_POST["onamae"]; ?>" // 단축형 (동일한 결과) value="<?=$_POST["onamae"]?>"
<?= 를 쓸 수 없는 환경
<?=는 PHP 5.4 이전에는 php.ini의 short_open_tag = On이어야만 동작했다. PHP 5.4 이후로는 항상 활성화되어 있다. 레거시 환경에서 작동하지 않을 경우 <?php echo ?>로 교체하면 된다.
// <?= 대신 확실히 동작하는 형태 value="<?php echo htmlspecialchars($_POST["onamae"], ENT_QUOTES, 'UTF-8'); ?>"
| 태그 |
의미 |
동작 조건 |
<?php ?> |
표준 PHP 태그 |
항상 동작 |
<?= ?> |
단축 echo 태그 |
PHP 5.4+ 항상 동작 / 이전 버전은 short_open_tag=On 필요 |
<? ?> |
구식 단축 태그 |
short_open_tag=On 필요 (권장하지 않음) |
4 hidden vs session — 데이터 전달 방법 비교
hidden 필드 외에 다른 방법은?
여러 페이지에 걸쳐 데이터를 유지하는 방법은 hidden 필드 외에도 있다. 각 방법의 특성을 알아 두면 상황에 맞게 선택할 수 있다.
hidden 필드 (이 예제)
클라이언트(브라우저)에 저장
HTML 소스에서 노출됨
추가 설정 불필요
폼 제출 흐름 내에서만 유효
민감 정보 저장 부적합
$_SESSION
서버에 저장
HTML에 노출 안 됨
session_start() 필요
페이지 간 자유롭게 공유
민감 정보도 안전하게 보관 가능
※ 민감한 데이터(로그인 상태, 권한, 결제금액 등)는 hidden이 아닌 $_SESSION에 저장해야 한다. hidden은 개발자도구에서 누구나 값을 바꿔 제출할 수 있어 위험하다.
5 데이터 흐름 전체 순서
3개 파일이 연쇄적으로 POST를 주고받는 흐름을 단계별로 따라가 보자.
1
form.html: 입력 후 "송신"onamae, honbun 입력 + user_id(hidden, 값 "0001") → POST → confirm.php
2
confirm.php: 내용 표시 + hidden에 데이터 담기$_POST 값을 화면에 print 출력. 동시에 FORM의 hidden INPUT에 재삽입
3
사용자가 내용 확인틀렸으면 브라우저 뒤로 가기로 form.html 복귀 (입력값은 사라짐에 주의)
4
"확인" 버튼 클릭confirm.php의 FORM — hidden 포함 전체 → POST → view.php
5
view.php: 최종 출력 및 처리$_POST["onamae"], $_POST["honbun"], $_POST["user_id"] 모두 접근 가능
※ 브라우저 뒤로 가기를 누르면 confirm.php 화면은 복원되지만 form.html의 입력값은 사라질 수 있다. 되돌아가기 버튼은 form4에서처럼 hidden 값을 다시 채워 form.html을 재구성하는 방식으로 구현한다.
6 hidden 필드와 XSS — 보안 점검
hidden에 값을 넣을 때도 이스케이프가 필요한가?
hidden 필드의 value에 사용자 입력을 그대로 넣으면 HTML 속성 탈출(attribute escape) 취약점이 생긴다. 예를 들어 이름에 " onmouseover="alert(1)를 입력하면 속성이 중단되고 이벤트 핸들러가 삽입될 수 있다.
// 위험한 코드 <INPUT type="hidden" name="onamae" value="<?=$_POST["onamae"]?>"> // 안전한 코드 — htmlspecialchars로 속성값 이스케이프 <INPUT type="hidden" name="onamae" value="<?= htmlspecialchars($_POST["onamae"], ENT_QUOTES, 'UTF-8') ?>">
※ 이 예제는 학습 목적으로 이스케이프를 생략했다. 실무에서는 HTML 속성 안에 삽입되는 모든 외부 입력에 htmlspecialchars(..., ENT_QUOTES, 'UTF-8')를 적용해야 한다.
| 위치 |
위험 |
방어 함수 |
HTML 본문 출력 (print $val) |
XSS — 스크립트 실행 |
htmlspecialchars() |
HTML 속성값 (value="$val") |
속성 탈출 — 이벤트 삽입 |
htmlspecialchars(..., ENT_QUOTES) |
| SQL 쿼리 삽입 |
SQL 인젝션 — 데이터 탈취 |
prepared statement (PDO) |
7 자주 하는 실수
| 실수 |
증상 |
해결 |
| confirm.php에 hidden 필드 누락 |
view.php에서 $_POST 값이 비어 있음 |
모든 전달 데이터를 hidden으로 재삽입 |
| hidden name 오타 |
view.php에서 해당 key Undefined index |
form.html name과 hidden name 정확히 일치 |
| <?= 를 지원 안 하는 설정 |
PHP 코드가 텍스트로 출력 |
PHP 5.4+ 확인 또는 <?php echo 사용 |
| hidden에 비밀번호 저장 |
HTML 소스에 그대로 노출 |
민감 정보는 세션($_SESSION)에 저장 |
| hidden value 이스케이프 미적용 |
속성값 탈출 공격 가능 |
htmlspecialchars(..., ENT_QUOTES) 적용 |
| user_id를 hidden으로 전달 후 서버 미검증 |
사용자가 값 조작 가능 |
서버에서 반드시 DB 등으로 유효성 재확인 |
3단계 폼 설계 체크리스트
- confirm.php의 FORM에 모든 데이터를 hidden으로 재삽입했는가?
- hidden value에 htmlspecialchars(ENT_QUOTES)를 적용했는가?
- 민감 데이터(금액, 권한, 비밀번호)는 hidden 대신 세션에 저장했는가?
- 서버(view.php)에서 hidden으로 받은 user_id 등을 DB로 재검증하는가?
핵심 한 줄 요약
form → confirm → view3단계 폼 — 확인 화면으로 실수 방지
type="hidden"화면에 안 보이지만 FORM과 함께 전송 — 데이터 릴레이 수단
<?=$_POST["key"]?>HTML 속성 안에 PHP 변수 끼워 넣는 단축 출력 태그
hidden ≠ 비밀소스보기에서 보임 — 민감 정보는 $_SESSION에 저장
hidden value 이스케이프htmlspecialchars(ENT_QUOTES) 필수 — 속성 탈출 공격 방어
Tags
#PHP #확인화면 #hidden필드 #3단계폼 #confirm페이지 #$_POST전달 #session비교 #XSS #short_open_tag #다단계폼 #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
PHP, 확인화면, hidden필드, 3단계폼, confirm페이지, $_POST전달, session비교, XSS, short_open_tag, 다단계폼, 웹개발, 티스토리
댓글