흐름을 제어하는 마법 - 조건문 (if, match)
1. 제어 구조(Control Structures)란?
프로그램의 코드는 기본적으로 위에서 아래로 물 흐르듯 순서대로 실행됩니다. 하지만 실무에서는 "로그인을 한 사람이면 회원 페이지를 보여주고, 아니면 로그인 창으로 보내라"처럼 상황에 따라 코드의 실행 흐름을 바꾸거나 갈라지게 해야 할 때가 무수히 많습니다.
이렇게 조건에 따라 코드의 방향을 조종하는 문법을 제어 구조(제어문)라고 부릅니다. 이번 강좌에서는 그중 가장 핵심인 조건문에 대해 알아보겠습니다.
2. 만약 ~라면: if 문
if는 영어로 "만약 ~라면"이라는 뜻이죠. PHP에서도 똑같습니다. "괄호 안의 조건이 참(true)이면 지정된 코드를 실행해라!"라는 뜻입니다.
<?php
$a = 3;
$b = 1;
// 조건: $a가 $b보다 크다면
if ($a > $b) {
echo "{$a}은(는) {$b}보다 큽니다.<br>";
echo "차이는 " . ($a - $b) . "입니다.<br>";
}
만약 $a가 0이었다면 조건이 거짓(false)이 되므로, 중괄호 { } 안의 코드는 완전히 무시되고 건너뜁니다.
선배의 조언: 중괄호는 선택이 아닌 필수!
실행할 명령이 단 한 줄뿐이라면 중괄호를 생략할 수도 있습니다. 하지만 나중에 코드를 수정하다가 중괄호가 없어서 생기는 황당한 버그(논리 오류)를 피하려면, 처음부터 무조건 중괄호{ }를 치는 습관을 들이는 것이 좋습니다.
그렇지 않다면: else 문
if문의 조건이 참이 아닐 때(거짓일 때) 실행할 코드를 덧붙이려면 else를 사용합니다.
<?php
$a = 3;
$b = 5;
if ($a > $b) {
echo "{$a}은(는) {$b}보다 큽니다.";
} else {
echo "{$a}은(는) {$b}보다 작거나 같습니다.";
}
여러 조건 이어붙이기: elseif 문
조건이 두 가지로만 나뉘지 않는 경우도 많습니다. 학점을 매기는 프로그램을 생각해 봅시다. 이럴 때는 elseif를 사용해 여러 조건을 기차처럼 이어 붙일 수 있습니다.
<?php
$score = 85;
if ($score >= 90) {
echo 'A 학점입니다.';
} elseif ($score >= 80) {
echo 'B 학점입니다.';
} elseif ($score >= 70) {
echo 'C 학점입니다.';
} else {
echo '분발하세요!';
}
// 출력 결과: B 학점입니다.
위에서부터 순서대로 조건을 검사하다가 가장 먼저 '참'이 되는 블록 하나만 실행하고 나머지 조건은 쳐다보지도 않고 전체 if문을 빠져나갑니다.
3. 현대적인 다중 분기: match 표현식 (PHP 8.0+)
하나의 변수가 어떤 값을 가지고 있느냐에 따라 여러 갈래로 나뉘어야 할 때가 있습니다. 과거에는 switch라는 문법을 썼지만, break를 빼먹으면 코드가 줄줄이 실행되는 등 버그를 유발하기 쉬운 치명적인 단점이 있었습니다.
최신 PHP에서는 이를 완벽하게 개선한 match 표현식을 강력히 권장합니다.
<?php
$status = 2;
// $status 값에 딱 맞는 결과를 찾아서 $label에 바로 대입합니다.
$label = match($status) {
1 => '활성 계정',
2 => '비활성 계정',
3 => '승인 대기 중',
default => '알 수 없는 상태', // 아무것도 해당하지 않을 때
};
echo $label; // 출력 결과: 비활성 계정
여러 값을 한 번에 묶기
조건이 여러 개일 때는 쉼표(,)로 깔끔하게 묶을 수 있습니다.
<?php
$lang = 'ko-KR';
$region = match($lang) {
'ko', 'ko-KR' => '대한민국',
'en', 'en-US' => '미국/영어권',
'ja' => '일본',
default => '기타 국가',
};
범위 조건 판단하기
match에 특정 값이 아닌 true를 던져주면, if-elseif 문처럼 값의 범위를 판단하는 데에도 아주 훌륭하게 쓸 수 있습니다.
<?php
$score = 85;
$grade = match(true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 70 => 'C',
default => 'F',
};
주의할 점:
match는switch와 다르게, 일치하는 값이 없는데default마저 없으면 곧바로 치명적 에러를 뿜어냅니다. 따라서 항상default를 안전하게 작성해 두는 것이 좋습니다.
4. 한 줄로 끝내는: 삼항 연산자 (?:)
정말 단순한 if-else 구조는 삼항 연산자를 이용해 한 줄로 아주 짧게 줄일 수 있습니다.
<?php
$age = 20;
// 구조: (조건) ? 참일 때 돌려줄 값 : 거짓일 때 돌려줄 값;
$status = ($age >= 18) ? '성인' : '미성년자';
echo $status; // 출력 결과: 성인
코드가 짧아져서 보기 좋지만, 이 삼항 연산자를 두 번 세 번 겹쳐 쓰게 되면(중첩) 나중에 본인도 해석하지 못할 만큼 난해한 암호문이 되어 버립니다. 조건이 조금이라도 복잡해진다 싶으면 망설이지 말고 정석대로 if-else 문이나 match를 사용하세요.