삼항 연산자는 표현식 하나에 들어가는 if/else입니다: condition ? valueIfTrue : valueIfFalse. 두 값 중 하나를 반환하므로 대입하거나, echo하거나, 함수에 넘길 수 있습니다.
$age를 15로, $items를 3으로 바꾸고 다시 실행해 보세요. 마지막 줄에서 삼항을 감싼 괄호에 주목하세요. 괄호가 없으면 .가 문자열을 먼저 연결해서 원하는 결과가 나오지 않습니다.
HTML 템플릿 속 삼항
삼항은 템플릿 안에서 CSS 클래스, 라벨, 속성을 고르는 일반적인 방법입니다. 이 블록은 URL에서 ?stock=을 읽습니다. 실행한 뒤 Page 탭의 링크를 클릭하면 같은 스크립트가 다른 값으로 다시 실행됩니다.
<?= ... ?>는 <?php echo ... ?>의 줄임으로, 마크업 안의 한 줄 조건을 읽기 쉽게 유지합니다.
짧은 삼항 ?:(엘비스 연산자)
가운데 부분을 생략하면 $a ?: $b가 됩니다. $a가 참으로 평가되면 $a를, 아니면 $b를 반환합니다. 빈 문자열이나 0도 기본값으로 대체해야 할 때 편리합니다.
거짓으로 평가되는 값은 false, 0, 0.0, "", "0", [], null입니다. 데이터에서 "0"이 실제 답이라면(수량 필드, PIN), 짧은 삼항은 그것을 버립니다.
?:와 ??
비슷해 보이지만 확인하는 것이 다릅니다. ?:는 왼쪽이 거짓으로 평가될 때 기본값으로 넘어갑니다. ??는 왼쪽이 null이거나 설정되지 않았을 때만 넘어가며, 없는 변수나 배열 키에 대해 경고하지 않습니다.
"값이 없을 수도 있다"(요청 데이터, 설정 배열, 선택적 키)에는 ??를 쓰세요. "값은 있지만 비어 있을 수 있다"에는 ?:를 쓰세요. ??와 ??=는 null 병합 연산자 페이지에서 자세히 다룹니다.
중첩 삼항에는 괄호가 필요하다
PHP 7은 a ? b : c ? d : e를 다른 거의 모든 언어와 달리 왼쪽에서 오른쪽으로 읽었고, 잘못된 결과를 냈습니다. PHP 8은 추측하기를 거부합니다.
<?php
echo $score > 90 ? "A" : $score > 80 ? "B" : "C";
PHP Fatal error: Unparenthesized `a ? b : c ? d : e` is not supported. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)` in /home/index.php on line 2
안쪽 삼항을 괄호로 감싸면 동작합니다.
짧은 삼항은 예외입니다. 위의 엘비스 예제처럼 $a ?: $b ?: $c는 괄호 없이 허용됩니다.
분기가 둘보다 많으면 match(true)
세 단계, 네 단계로 중첩된 삼항은 괄호가 있어도 읽기 어렵습니다. 대상으로 true를 쓴 match는 위에서부터 조건을 확인하고 처음 일치하는 갈래를 반환합니다.
삼항은 한 줄에 결과가 둘일 때만 쓰고, 세 번째가 필요해지면 바로 match나 if/elseif 체인을 쓰세요.
자주 묻는 질문
PHP의 삼항 연산자란 무엇인가요?
값을 반환하는 if/else의 짧은 형태입니다: $label = $age >= 18 ? 'adult' : 'minor';. ? 앞의 조건이 참이면 ? 뒤의 표현식이, 아니면 : 뒤의 표현식이 쓰입니다.
PHP에서 ?:는 무슨 뜻인가요?
$a ?: $b는 짧은 삼항(엘비스 연산자라고도 함)입니다. $a가 참으로 평가되면 $a를, 아니면 $b를 반환하므로 '' ?: 'default'는 'default'입니다. $a ? $a : $b와 같지만 $a는 한 번만 평가됩니다.
PHP에서 삼항 연산자를 중첩할 수 있나요?
괄호가 있을 때만 가능합니다. PHP 8부터 $a ? 'x' : $b ? 'y' : 'z'는 치명적 에러이므로 $a ? 'x' : ($b ? 'y' : 'z')로 쓰세요. 분기가 둘보다 많으면 match(true)나 if/elseif 체인이 읽기 쉽습니다.
else 부분 없이 삼항을 쓸 수 있나요?
아니요, 삼항에는 항상 두 분기가 필요합니다. "이 값을 쓰거나 기본값으로"라면 $x ?: 'default'나 $x ?? 'default'로 쓰고, 조건이 맞을 때만 무언가를 하려면 일반 if나 $condition && doSomething();를 쓰세요.