PHP에서 매일 쓰는 타입은 여덟 가지입니다: int, float, string, bool, array, object, null, 그리고 주고받는 함수를 위한 callable. 변수에는 고정된 타입이 없고, 현재 값에 타입이 있습니다. var_dump($x)는 타입과 값을 모두 보여 주고, gettype($x)는 타입을 문자열로 반환합니다.
첫 번째 열은 gettype(), 두 번째 열은 get_debug_type()입니다. 값을 직접 바꾸고 다시 실행해 보세요. 몇몇 이름이 서로 다릅니다. gettype은 역사적인 이유로 integer, double, boolean이라고 하고, get_debug_type은 타입 선언의 이름(int, float, bool)을 쓰며 객체에는 클래스 이름을 반환합니다.
PHP 타입 한눈에 보기
| 타입 | 예 | 참고 |
|---|---|---|
int | 42, -7, 0x1A, 1_000_000 | 정수, 최신 시스템에서는 64비트 |
float | 3.14, 1.5e3 | 소수, 모든 언어처럼 근사값 |
string | "hi", 'hi' | 문자가 아니라 바이트의 나열 |
bool | true, false | 대소문자 무관(TRUE도 동작) |
array | [1, 2], ["a" => 1] | 순서 있는 맵: 리스트와 딕셔너리를 겸함 |
object | new User(), new stdClass() | 클래스의 인스턴스 |
null | null | null 타입의 유일한 값, "설정된 값 없음"도 뜻함 |
callable | 'strlen', fn($x) => $x * 2 | 호출할 수 있는 모든 것 |
iterable | 배열 또는 Traversable 객체 | foreach가 받는 것 |
resource | fopen()의 결과 | PHP 바깥의 무언가에 대한 핸들 |
var_dump로 값 살펴보기
var_dump는 실제로 무엇을 가지고 있는지 보는 도구입니다. 타입, 값, 그리고 문자열이면 바이트 단위 길이를 출력합니다.
echo라면 처음 세 개에 모두 10을 출력해서 차이를 숨깁니다. string(5) "café"의 길이는 바이트 수이며, 그래서 ASCII가 아닌 텍스트에서는 strlen과 mb_strlen이 다릅니다.
정수와 실수
정수는 소수점 없는 수입니다. 리터럴은 가독성을 위해 밑줄을 쓸 수 있고, 16진수, 8진수, 2진수 표기도 가능합니다. 실수(float)는 소수점이나 지수가 있는 수이며, 모든 언어처럼 대부분의 소수를 근사값으로 저장합니다.
float를 ==로 비교하지 마세요. 차이를 작은 허용 오차와 비교하거나, 먼저 양쪽을 반올림하세요. 금액은 센트 단위 정수로 저장하세요.
불리언과 false로 취급되는 값
bool은 true 또는 false입니다. PHP가 조건을 기대하는 곳(if, while, !)에서는 모든 값이 bool로 변환되며, 다음의 짧은 목록이 false로 취급됩니다: false, 0, 0.0, "", "0", [], null. 나머지는 모두 true입니다. 표는 각 값의 타입, bool 변환 결과, 숫자 여부를 보여 줍니다.
| $x | gettype | bool | is_numeric |
|---|---|---|---|
| 0 | |||
| 1 | |||
| -1 | |||
| 0.0 | |||
| 1.5 | |||
| "0" | |||
| "" | |||
| " " | |||
| "0.0" | |||
| "10" | |||
| "1e1" | |||
| "abc" | |||
| "null" | |||
| true | |||
| false | |||
| null | |||
| [] | |||
| [0] |
의외의 값은 "0.0", " ", "null"입니다. 셋 다 "0"이 아닌 비어 있지 않은 문자열이므로 true이고, if ($value)는 이들에 대해 본문을 실행합니다.
배열, 객체, null
배열은 정수나 문자열 키 아래에 어떤 값이든 섞어 담습니다. 객체는 클래스의 인스턴스입니다. stdClass는 간단한 객체를 위한 PHP의 빈 클래스이고, (object)는 배열을 객체로 바꿉니다. null은 "값 없음"을 뜻합니다.
is_* 함수로 타입 확인
각 타입에는 true나 false를 반환하는 검사 함수가 있습니다. is_numeric은 is_int와 다릅니다. 숫자 형태의 문자열도 받아들이므로 폼 입력을 확인할 때 원하는 동작입니다.
그 밖에 is_bool, is_array, is_object, is_null, is_callable, is_iterable이 있고, 특정 클래스는 $x instanceof ClassName으로 확인합니다.
타입 저글링과 strict types
PHP는 연산자에 다른 타입이 필요하면 자동으로 변환합니다. 산술에 쓰인 숫자 형태의 문자열은 숫자가 되고, .는 숫자를 문자열로 바꿉니다. 전혀 숫자가 아닌 문자열은 더할 수 없으며, PHP 8은 TypeError를 던집니다.
타입이 지정된 매개변수도 변환됩니다. 단, 파일이 declare(strict_types=1);로 시작하면 잘못된 스칼라 타입으로 호출할 때 변환되지 않고 실패합니다.
의도적으로 변환하려면 캐스트하세요: (int) "42", (float) "3.5", (string) 10, (bool) "0". 모든 캐스트와 경계 사례는 타입 캐스팅 페이지에서 다룹니다.
흔한 실수: 서로 다른 타입을 ==로 비교
==는 비교하기 전에 변환하므로, 타입이 다른 두 값이 버그를 일으키는 방식으로 "같아질" 수 있습니다. 예를 들어 "1e1" == "10"(둘 다 숫자 10)이나 null == false입니다. 변환을 원하지 않는다면 타입까지 같아야 하는 ===를 쓰세요.
PHP 8은 최악의 경우를 고쳤습니다. "abc" == 0은 예전에는 true였지만 이제는 false입니다. 숫자가 아닌 문자열은 문자열로 비교되기 때문입니다. 전체 표는 비교 연산자 페이지에 있습니다.
자주 묻는 질문
PHP에서 변수의 타입은 어떻게 확인하나요?
var_dump($x)는 int(5)처럼 타입과 값을 출력합니다. gettype($x)는 타입 이름을 문자열로("integer"), get_debug_type($x)는 최신 이름을("int", 객체는 클래스 이름) 반환합니다. 특정 타입인지 확인하려면 is_int, is_string, is_array 등 is_* 함수를 쓰세요.
gettype이 float에 대해 "double"을 반환하는 이유는?
역사적인 이유로 gettype()은 float를 "double"로, 정수를 "integer"로 보고합니다. PHP 8에서 추가된 get_debug_type()은 타입 선언에 쓰는 이름과 같은 "float"와 "int"를 반환합니다.
PHP에서 false로 취급되는 값은 무엇인가요?
bool로 변환하면 다음이 false입니다: false, 0, 0.0, "", "0", [], null. 그 밖의 모든 값은 true이며, "0.0", " ", "false"도 포함됩니다.
PHP의 최대 정수는 얼마인가요?
PHP_INT_MAX이며, 64비트 시스템에서는 9223372036854775807입니다. 그 이상을 더해도 순환하지 않고, 결과가 float가 되어 정밀도를 잃습니다.
PHP는 강타입 언어인가요, 약타입 언어인가요?
PHP는 동적 타입이며 기본적으로 가능하면 타입을 변환합니다("10" + 5는 15). 파일 맨 위에 declare(strict_types=1);를 두면, 그 파일에서 타입이 지정된 함수를 호출할 때 잘못된 스칼라 타입을 변환하지 않고 TypeError로 거부합니다.