시작 오늘 분석할 코드
라디오버튼은 같은 name을 가진 항목 중 오직 하나만 선택된다. 브라우저가 이 규칙을 강제하므로 PHP는 항상 단일 문자열 값을 받는다. 체크박스처럼 배열이 필요 없다.
form.html — 라디오버튼 폼
<FORM name="form1" method="post" action="view.php"> 성별:<BR> <INPUT type="radio" name="gender" value="남">남<BR> // radio는 하나만 체크할 수 있기 때문에 배열로 name key를 만들 필요 없음 <INPUT type="radio" name="gender" value="여">여<BR> <INPUT type="submit" value="송신"> </FORM>
view.php — 수신 처리
<?php if(isset($_POST["gender"]) && ($_POST["gender"] == "남" || $_POST["gender"] == "여")){ print "성별:<BR>"; print $_POST["gender"]; }else{ print "성별을 선택하세요.<BR>"; } ?>
실제 출력 미리보기
▼ 폼 화면 (form.html)
▼ 결과 화면 (view.php) — "남" 선택 시
성별:
남
용어 핵심 용어 정리
radio같은 name 그룹에서 하나만 선택되는 HTML input type. 브라우저가 상호 배타성 강제
name 공유같은 name을 가진 라디오버튼들은 하나의 그룹으로 동작. 하나 선택 시 다른 것 해제
$_POST["gender"]선택된 라디오버튼의 value 하나. 미선택 시 키 자체가 없음 (체크박스와 동일)
isset()라디오버튼 미선택 시 $_POST에 키가 없어서 직접 접근하면 경고. 반드시 isset으로 선검사
값 유효성 검사isset만으로는 부족. 예상 외 값(조작된 요청)을 막기 위해 == 비교로 허용값 명시
&& 연산자PHP 논리 AND. 왼쪽 조건이 거짓이면 오른쪽 평가 안 함 (단락 평가)
|| 연산자PHP 논리 OR. 왼쪽이 참이면 오른쪽 평가 안 함. 여러 허용값 중 하나만 맞으면 통과
value 속성사용자에게 보이는 라벨(남/여)과 서버로 전송되는 값(남/여)이 이 예시에서는 동일
1 라디오버튼이 체크박스와 다른 점
왜 name에 [] 없이 같은 name을 쓰는가
체크박스는 여러 개를 동시에 선택할 수 있어서 name="hobby[]"처럼 배열을 만든다. 라디오버튼은 같은 name 그룹에서 무조건 하나만 선택된다. 사용자가 "남"을 선택한 후 "여"를 클릭하면 "남"이 자동으로 해제된다 — 브라우저가 이 규칙을 강제한다.
그 결과 서버에는 항상 단일 문자열 하나가 전송된다. 배열이 필요 없으므로 []를 붙이지 않는다.
checkbox
여러 개 동시 선택 가능
name에 [] 필요
→ $_POST["k"] = ["a","b"]
implode()로 배열 처리
radio
같은 그룹에서 하나만 선택
name에 [] 불필요
→ $_POST["k"] = "a"
직접 문자열 비교
2 같은 name으로 그룹 만드는 원리
name이 같으면 하나의 라디오 그룹
HTML은 name 속성이 같은 라디오버튼들을 자동으로 하나의 그룹으로 인식한다. 이 그룹 안에서 하나를 선택하면 나머지는 모두 해제된다. 반대로 name이 다른 라디오버튼은 서로 독립적이어서 각 그룹에서 하나씩 선택 가능하다.
<!-- 두 라디오버튼이 같은 그룹 (name="gender") --> <INPUT type="radio" name="gender" value="남"> 남 <INPUT type="radio" name="gender" value="여"> 여 <!-- 서로 다른 그룹 — 각각 하나씩 선택 가능 --> <INPUT type="radio" name="gender" value="남"> 남 <INPUT type="radio" name="age" value="20대"> 20대 // 별도 그룹
※ 같은 form 안이라도 name이 다르면 각자 독립된 그룹이다. name="gender"와 name="age"는 서로 영향 안 줌.
3 isset + 값 비교 이중 검사
왜 단순 isset만으로는 부족한가
이 코드의 조건은 두 단계로 이루어진다:
if(isset($_POST["gender"]) // ① 키 존재 여부 && ($_POST["gender"] == "남" || $_POST["gender"] == "여")) // ② 허용값 확인
① isset()은 키가 존재하는지 확인한다. 아무것도 선택 안 하면 키 자체가 없으므로 false가 된다.
② 키가 있다 해도 값이 "남" 또는 "여"인지 확인한다. 브라우저 폼을 사용하면 항상 이 두 값 중 하나지만, HTTP 요청을 직접 조작하면 "관리자"처럼 임의 값을 보낼 수 있다. 값 비교로 예상 외 입력을 거른다.
⚠ isset만 쓰면: curl 등으로 gender=관리자를 보내도 통과. 민감한 분기(권한, 결제)에서는 반드시 허용 값 목록과 비교해야 한다.
4 단락 평가(Short-circuit)와 순서의 중요성
&&, || 는 왼쪽부터 평가하고 결과가 정해지면 멈춘다
PHP의 &&는 왼쪽이 false면 오른쪽을 아예 평가하지 않는다. 그래서 isset()을 앞에 두는 것이 중요하다. isset 없이 바로 $_POST["gender"] == "남"을 쓰면, 키가 없을 때 "Undefined index" 경고가 먼저 발생한다.
// 올바른 순서: isset이 false면 == 비교 자체를 건너뜀 if(isset($_POST["gender"]) && $_POST["gender"] == "남") // 잘못된 순서: key가 없으면 == 비교에서 경고 발생 if($_POST["gender"] == "남" && isset($_POST["gender"])) // ❌
※ 이처럼 먼저 안전 확인(null check, isset)을 하고 그 다음 값 사용 — 이 패턴은 PHP 전체에서 반복되는 기본 원칙이다.
5 라디오버튼 미선택 시 동작
선택 안 하고 폼을 제출하면 어떻게 되나
라디오버튼도 체크박스처럼 아무것도 선택하지 않으면 해당 name의 키가 $_POST에 아예 없다. 브라우저는 선택되지 않은 라디오버튼을 폼 데이터에 포함시키지 않기 때문이다.
// 아무것도 선택 안 한 경우 $_POST 내용: $_POST = [] // gender 키가 아예 없음 // isset($_POST["gender"]) → false → else 분기 진입 print "성별을 선택하세요.<BR>";
기본값 설정으로 미선택 방지하기
checked 속성을 추가하면 페이지 로드 시 해당 라디오가 미리 선택됨
<INPUT type="radio" name="gender" value="남" checked>
- UX 개선 목적이지만, 서버 측 유효성 검사는 여전히 필요
6 자주 하는 실수
| 실수 |
증상 |
해결 |
| 각 라디오버튼에 다른 name 사용 |
그룹이 분리돼서 여러 개 동시 선택 가능해짐 (라디오버튼 의미 소실) |
같은 그룹의 모든 라디오에 동일한 name 사용 |
| name에 [] 붙이기 (name="gender[]") |
$_POST["gender"]가 배열로 와서 문자열 비교 불일치 — 항상 else 분기 |
라디오버튼은 단일값. [] 없이 name="gender"로 사용 |
| isset 없이 직접 값 비교 |
미선택 제출 시 "Undefined index: gender" 경고 |
isset($_POST["gender"]) &&를 앞에 붙여 존재 먼저 확인 |
| value 속성 없이 라디오버튼 생성 |
선택 시 "on"이라는 문자열이 전송됨. 비교 조건에서 항상 불일치 |
각 라디오버튼에 구분 가능한 value 명시 |
| 값 비교 없이 isset만으로 처리 |
HTTP 요청 조작으로 임의 값 전송 시 그대로 출력됨 (XSS 가능성) |
허용 값 목록과 == 비교 추가. 또는 htmlspecialchars()로 출력 시 이스케이프 |
보충 in_array()로 허용값 비교 개선
허용값이 늘어날 때 || 대신 배열로 관리하는 방법
이 예제는 허용값이 "남", "여" 두 개라서 == "남" || == "여"로 충분하다. 하지만 선택지가 5~10개로 늘어나면 조건문이 길어진다. 이때 in_array()를 쓰면 허용값 목록을 배열로 관리해서 코드가 깔끔해진다.
// 기존 방식 (선택지 많아지면 길어짐) if(isset($_POST["gender"]) && ($_POST["gender"] == "남" || $_POST["gender"] == "여")) // in_array() 방식 (허용값 목록을 한눈에 확인) $allowed = ["남", "여"]; if(isset($_POST["gender"]) && in_array($_POST["gender"], $allowed)){ print $_POST["gender"]; } // 선택지가 많은 예시 — 배열 방식이 훨씬 유리 $allowed_ages = ["10대", "20대", "30대", "40대", "50대 이상"];
※ in_array() 세 번째 인수에 true를 넣으면 타입까지 엄격하게 비교한다 (strict 모드). 문자열 "1"과 정수 1을 다르게 취급해야 할 때 사용.
in_array()는 배열 안에 해당 값이 있으면 true, 없으면 false를 반환한다. isset()과 조합해서 먼저 키 존재를 확인한 뒤 사용하는 것이 안전한 패턴이다.
핵심 한 줄 요약
radio vs checkbox라디오는 그룹 내 단일 선택 → 배열 불필요, 문자열 직접 비교
isset() 선행 필수미선택 시 키가 없으므로 exists 확인 후 값 접근
값 비교 이중 검사isset + 허용값 == 비교로 조작된 요청 차단
&& 단락 평가isset을 왼쪽에 두면 false 시 오른쪽 평가 건너뜀 — 안전한 접근 보장
Tags
#PHP #라디오버튼 #radio #단일선택 #$_POST #isset #유효성검사 #폼처리 #조건분기 #웹개발
▼ 티스토리 태그 입력란 복사용
PHP, 라디오버튼, radio, 단일선택, $_POST, isset, 유효성검사, 폼처리, 조건분기, 웹개발
댓글