PHP 상수 선언: define()과 const의 기본 개념
PHP에서 상수를 선언하는 방법은 크게 두 가지가 있습니다. 바로 define() 함수와 const 키워드입니다. 두 방식 모두 스크립트 실행 중 변경되지 않는 고정값을 정의하는 데 사용되지만, 내부 동작 방식과 활용 범위에는 중요한 차이가 있습니다.
기본 문법
<?php
const VAR = 'FOO';
define('VAR', 'FOO');
?>
문법만 보면 비슷해 보이지만, 실제로는 여러 면에서 다르게 동작합니다. 아래에서 핵심 차이점을 하나씩 살펴보겠습니다.
1. 컴파일 타임 vs 런타임
가장 근본적인 차이는 상수가 정의되는 시점입니다. const는 컴파일 타임(compile time)에 상수를 정의하는 반면, define()은 런타임(runtime)에 상수를 정의합니다. 이 차이가 이후에 설명할 다른 특징들의 원인이 됩니다.
2. 조건문 내부에서의 사용 여부
const 키워드는 if 문과 같은 조건 블록 안에서 상수를 선언할 수 없습니다. 반면 define()은 조건문 내부에서도 자유롭게 사용할 수 있어, 특정 조건이 충족될 때만 상수를 정의하는 유연한 코드 작성이 가능합니다.
<?php
if ($condition) {
const VAR = 'FOO'; // 유효하지 않음 (컴파일 오류)
}
if ($condition) {
define('VAR', 'FOO'); // 유효함
}
?>
3. 허용되는 값의 범위
const는 정적 스칼라 값(숫자, 문자열, true, false, null, __FILE__ 등 이미 정의된 상수)만 값으로 받을 수 있습니다. 반면 define()은 변수나 함수 호출 결과를 포함한 모든 표현식(expression)을 값으로 사용할 수 있습니다.
4. 대소문자 구분
const로 선언한 상수는 항상 대소문자를 구분합니다(case-sensitive). 반면 전통적으로 define()은 세 번째 인수로 true를 전달하면 대소문자를 구분하지 않는 상수를 만들 수 있었습니다.
참고: 대소문자 비구분 옵션은 PHP 7.3부터 지원이 중단(deprecated)되었고, PHP 8.0부터는 완전히 제거되었습니다. 따라서 최신 PHP 버전에서는 define()으로 선언한 상수 역시 항상 대소문자를 구분합니다.
5. 클래스 및 인터페이스 내 사용
const는 클래스나 인터페이스 내부에서 클래스 상수 또는 인터페이스 상수를 선언하는 데 사용할 수 있습니다. 하지만 define()은 이러한 용도로 사용할 수 없습니다.
<?php
class abc {
const VAR = 2; // 유효함
}
echo abc::VAR; // 유효함
// 반면
class xyz {
define('XUV', 2); // 유효하지 않음 (오류 발생)
}
?>
위 예제에서 확인할 수 있듯이, const 키워드를 사용하면 클래스 내부에 상수를 선언하고 외부에서 접근할 수 있지만, define()은 클래스 내부에서 상수를 선언하는 데 사용할 수 없습니다.
핵심 차이점 요약
| 구분 | const | define() |
|---|---|---|
| 정의 시점 | 컴파일 타임 | 런타임 |
| 조건문 내 사용 | 불가 | 가능 |
| 값의 형태 | 정적 스칼라만 허용 | 모든 표현식 허용 |
| 대소문자 구분 | 항상 구분 | 옵션 설정 가능 (PHP 8부터는 항상 구분) |
| 클래스/인터페이스 내 사용 | 가능 | 불가 |
마무리
간단한 전역 상수라면 어느 방식을 사용해도 무방하지만, 클래스 상수가 필요하거나 성능이 중요한 경우에는 const, 런타임에 동적으로 상수를 정의해야 하는 경우에는 define()을 선택하는 것이 좋습니다. 각 방식의 특성을 이해하고 상황에 맞게 활용하면 더 깔끔하고 안정적인 PHP 코드를 작성할 수 있습니다.