session_start()로 페이지 간 데이터를 유지하고, 확인 버튼과 되돌아가기 버튼으로 두 갈래 처리하는 패턴
시작 오늘 분석할 코드
이 예제는 3개의 PHP 파일로 구성된 폼 확인 시스템이다. form.html에서 입력 → confirm.php에서 세션 저장 + 확인 화면 표시 → view.php에서 확인/되돌아가기 분기 처리. 이때 HTTP는 무상태(stateless) 프로토콜이라 페이지 간 데이터를 자동으로 넘겨주지 않는다. 세션이 그 다리 역할을 한다.
<?phpsession_start(); ?><?phpif(isset($_POST["confirm"])){ // 확인 버튼을 누른 경우print$_SESSION["onamae"] . "님으로부터의 메시지"; print"<BR>본문:<BR>" . nl2br($_SESSION["honbun"]); }elseif(isset($_POST["back"])){ // 되돌아가기 버튼을 누른 경우 — 세션 값으로 폼 복원?><FORMmethod="post"action="confirm.php"> 이름:<INPUTtype="text"name="onamae"value="<?=$_SESSION["onamae"]?>"> 본문:<TEXTAREAname="honbun"><?=$_SESSION["honbun"]?></TEXTAREA><INPUTtype="submit"value="발송"></FORM><?php }else{ print"오류입니다."; } ?>
실제 흐름 미리보기
① form.html
이름:
본문:
→
② confirm.php
이름: 홍길동 본문: 안녕하세요!
→
③ view.php
홍길동님으로부터의 메시지
본문: 안녕하세요!
용어 핵심 용어 정리
session_start()세션 사용 선언. 반드시 출력 전(HTML 이전)에 호출해야 함. 세션 파일 생성 또는 재연결
$_SESSION서버 측에 저장되는 슈퍼글로벌 배열. 같은 세션 ID를 가진 요청 간 데이터 공유
세션 ID서버가 클라이언트에 부여하는 고유 식별자. 보통 PHPSESSID 쿠키로 브라우저가 보관
nl2br()문자열의 줄바꿈(\n)을 HTML <br>로 변환. textarea 입력 줄바꿈을 웹에서 표시
hidden input화면에 안 보이지만 폼과 함께 전송되는 값. user_id처럼 사용자가 직접 입력 안 하는 데이터
name="confirm"submit 버튼에 name 부여. 클릭된 버튼의 name이 $_POST에 포함되어 어떤 버튼인지 판단 가능
3페이지 구성form → confirm → view 패턴. 사용자가 제출 전 내용을 한 번 더 확인하는 UX 흐름
statelessHTTP 프로토콜의 무상태 특성. 각 요청은 독립적이라 세션 없이는 이전 요청 데이터를 모름
1 세션이 필요한 이유 — HTTP는 무상태
confirm.php → view.php로 데이터를 어떻게 넘기는가
form.html에서 confirm.php로는 $_POST로 데이터가 온다. 그런데 confirm.php에서 view.php로 넘어갈 때 문제가 생긴다. 두 번째 폼 제출에서 $_POST에는 "confirm" 또는 "back" 버튼 정보만 있고, 원래 이름·본문 데이터가 없다.
세션은 이 문제를 서버 측 저장소로 해결한다. confirm.php에서 $_SESSION에 데이터를 저장해두면, view.php에서 같은 세션 ID로 그 데이터를 꺼낼 수 있다.
hidden input으로 넘기기
확인 폼에 hidden으로 숨겨서 다시 전송 → HTML 소스 노출 (조작 가능) → 데이터 많으면 폼이 복잡 → 브라우저 뒤로가기 시 재전송 경고
세션으로 넘기기
서버 측에 안전 보관 → 클라이언트에 원본 미노출 → 어느 페이지서든 접근 가능 → 세션 만료까지 유지
2 session_start()의 위치가 중요한 이유
HTML 출력 이전에 반드시 호출해야 한다
세션은 내부적으로 Set-Cookie HTTP 헤더로 PHPSESSID를 클라이언트에 전달한다. HTTP 헤더는 모든 HTML 출력 이전에 전송해야 한다. HTML을 한 글자라도 출력한 뒤 session_start()를 호출하면 "Cannot modify header information — headers already sent" 오류가 난다.
// 올바른 위치 (파일 맨 위)<?phpsession_start(); ?><HTML>... // 잘못된 위치 (HTML 출력 후)<HTML><HEAD><TITLE>테스트</TITLE></HEAD><?phpsession_start(); ?>// ❌ "headers already sent" 오류
⚠ 파일 상단에 공백이나 BOM(Byte Order Mark)이 있어도 출력으로 간주한다. PHP 파일은 session_start() 전에 어떤 문자도 없어야 한다.
3 submit 버튼의 name으로 어떤 버튼을 눌렀는지 판단
같은 form 안에 두 개의 submit 버튼
confirm.php의 폼에는 "확인"과 "되돌아가기" 두 개의 submit 버튼이 있다. HTML 폼은 클릭된 submit 버튼의 name과 value를 POST 데이터에 포함한다. 클릭하지 않은 버튼은 포함되지 않는다. 이를 이용해 view.php에서 isset($_POST["confirm"])과 isset($_POST["back"])으로 분기한다.
<INPUTtype="submit"value="확인"name="confirm"><INPUTtype="submit"value="되돌아가기"name="back">// "확인" 클릭 시 $_POST: {"confirm": "확인"}// "되돌아가기" 클릭 시 $_POST: {"back": "되돌아가기"}// view.php 분기:if(isset($_POST["confirm"])){ // 확인 버튼 } elseif(isset($_POST["back"])){ // 되돌아가기 버튼 } else { // 직접 접근 등 예외 }
반응형
4 nl2br() — textarea 줄바꿈 표현
왜 textarea 본문에 nl2br이 필요한가
textarea에서 Enter로 입력한 줄바꿈은 내부적으로 \n(줄바꿈 문자)이다. 이를 그대로 HTML에 출력하면 브라우저는 공백으로 렌더링한다. nl2br()은 \n 앞에 <BR>을 삽입해서 웹 화면에서도 줄바꿈으로 보이게 한다.
$text = "1번 줄\n2번 줄\n3번 줄"; print$text; // 브라우저 표시: "1번 줄 2번 줄 3번 줄" (한 줄)printnl2br($text); // "1번 줄<br>\n2번 줄<br>\n3번 줄" → 3줄로 표시
※ nl2br은 \n을 <br>\n으로 변환한다 — 줄바꿈 문자를 삭제하지 않고 앞에 <br>만 추가한다. HTML 소스에서 줄바꿈이 유지돼 읽기 편하다.
5 되돌아가기 시 세션으로 폼 값 복원
브라우저 뒤로가기 대신 서버에서 폼을 재구성하는 방법
"되돌아가기" 버튼을 누르면 view.php에서 세션에 저장된 값을 꺼내 폼의 value 속성에 채워서 다시 입력 폼을 렌더링한다. 사용자 입장에서는 입력했던 내용이 그대로 유지된 채 수정 화면으로 돌아가는 것처럼 보인다.
// view.php — 되돌아가기 분기에서 폼 복원 이름:<INPUTtype="text"name="onamae"value="<?=$_SESSION["onamae"]?>"> 본문:<TEXTAREAname="honbun"><?=$_SESSION["honbun"]?></TEXTAREA>
textarea는 value 속성이 없다. 내용을 여는 태그와 닫는 태그 사이에 직접 출력해야 초기값이 채워진다.
6 자주 하는 실수
실수
증상
해결
session_start() 호출을 빠뜨림
$_SESSION이 비어있어 view.php에서 이름·본문이 안 보임
세션을 사용하는 모든 파일 상단에 session_start() 추가
session_start() 이후에 HTML 출력
"Cannot modify header information — headers already sent" 오류
session_start()를 파일 맨 위, HTML 이전에 배치
confirm.php에서 $_POST 대신 $_SESSION으로 화면 표시
처음 방문 시 세션이 없어 빈 화면 또는 이전 방문자 데이터 표시
confirm.php 화면에는 방금 받은 $_POST 사용, $_SESSION은 다음 페이지 전달용
submit 버튼에 name 없이 분기 시도
confirm/back 어느 쪽도 isset에서 false가 되어 항상 else(오류) 분기
분기할 각 submit 버튼에 고유한 name 속성 추가
textarea 복원을 value 속성으로 시도
textarea에는 value 속성이 없어서 빈 칸으로 표시됨
<textarea>내용</textarea> 사이에 직접 출력
핵심 한 줄 요약
3페이지 구성form→confirm→view. HTTP 무상태 문제를 세션으로 데이터 연결
session_start()반드시 HTML 이전 파일 맨 위에. 세션 사용하는 모든 파일에
submit name으로 분기클릭된 버튼의 name만 $_POST에 포함 → isset으로 어떤 버튼인지 판단
nl2br()textarea 줄바꿈(\n)을 HTML <br>로 변환해야 웹에서 줄바꿈 표시
댓글