본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

PHP 라디오버튼 — 단일 선택값 처리 완전 정리

by 왕진 2026. 7. 8.
반응형

 

 

Web Development · PHP Form

라디오버튼 단일 선택값 처리 — PHP 폼 완전 정리

체크박스와 달리 하나만 선택 가능한 라디오버튼, name 중복과 isset + 조건 분기로 안전하게 처리하는 법
시작 오늘 분석할 코드

라디오버튼은 같은 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, 유효성검사, 폼처리, 조건분기, 웹개발
반응형

댓글