number_format($number, $decimals)는 천 단위 구분 기호와 고정된 소수점 자리를 가진 문자열로 숫자를 반환합니다: number_format(1234567.891, 2)는 "1,234,567.89"를 반환합니다. 인수가 하나면 정수로 반올림합니다: number_format(1234567.891)은 "1,234,568"입니다.
네 가지 매개변수
number_format(
float $num,
int $decimals = 0,
?string $decimal_separator = ".",
?string $thousands_separator = ","
): string
세 번째 인수는 정수 부분과 소수 부분 사이의 문자이고, 네 번째는 세 자리 묶음 사이의 문자입니다. 둘 다 빈 문자열이나 멀티바이트 문자를 포함해 어떤 문자열이든 될 수 있습니다. 아래에서 구분 기호를 바꿔 각 스타일을 확인해 보세요.
로케일 데이터(CLDR)는 숫자가 두 줄로 나뉘지 않도록 프랑스어에는 좁은 줄 바꿈 없는 공백(U+202F)을, 러시아어에는 줄 바꿈 없는 공백(U+00A0)을 씁니다. HTML에서는 일반 공백 대신 "\u{202F}"나 "\u{00A0}"을 구분 기호로 넘기세요.
천 단위 구분 기호 없이 숫자 포맷하기
네 번째 인수로 ''를 넘기세요. 고정된 소수점 자리를 가진 평범한 숫자가 되며, 결제 게이트웨이, CSV 내보내기, <input type="number"> 값이 기대하는 형태입니다.
마지막 줄에서는 형 변환 전의 round()가 중요합니다. 19.9 * 100은 1989.9999999999998로 저장되므로 (int)만 쓰면 1989로 잘립니다.
number_format의 반올림 방식
number_format()은 round()처럼 0에서 먼 쪽으로 반올림하므로 0.5는 1이 되고 -2.5는 -3이 됩니다. 2.675 같은 값의 아주 작은 이진 오차도 보정하므로 sprintf('%.2f')와 결과가 다를 수 있습니다.
2.675는 이진수로 정확히 저장할 수 없고, 저장된 값은 그보다 아주 조금 작습니다. sprintf()는 그 저장된 값을 포맷해서 2.67을 얻고, number_format()과 round()는 그것을 여러분이 쓴 2.675로 취급합니다. 특정 반올림 규칙이 필요하면 먼저 round(), floor(), ceil()을 직접 호출하고(반올림과 수학 참고) 그 결과를 number_format()에 넘기세요.
금액과 여러 통화 포맷하기
number_format()은 통화를 전혀 모르므로 기호는 직접 붙여야 합니다. 마이너스 기호는 통화 기호 앞에 두고, 엔화에는 소수점이 없다는 것을 기억하세요.
나라마다 올바른 기호 위치까지 맞추는 로케일 인식 출력에는 intl 확장의 NumberFormatter가 모든 일을 해 줍니다.
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo $fmt->formatCurrency(1234.5, 'EUR'); // 1.234,50 € (a no-break space before €)
intl 확장이 필요한데 모든 곳에 설치되어 있지는 않으므로, 기호를 직접 붙이는 number_format()이 이식성 있는 선택입니다.
결과는 숫자가 아니라 문자열
number_format()의 가장 흔한 버그입니다. 값을 포맷한 다음 그것으로 계산하는 것입니다. "1,234.50"은 숫자 문자열이 아니므로 PHP는 쉼표 앞의 1만 읽습니다.
<?php
echo number_format(1234.5, 2) + 1;
Warning: A non-numeric value encountered in /home/index.php on line 2
2
그런 문자열을 다시 number_format()에 넘기면 더 나쁩니다. TypeError: number_format(): Argument #1 ($num) must be of type int|float, string given을 던집니다. 계산에는 원래 숫자를 두고 출력하는 순간에만 포맷하세요. 폼이나 파일에서 포맷된 문자열을 받았다면 먼저 구분 기호를 제거하세요.
채우기, 정렬, 숫자 앞의 플러스 기호에는 sprintf()를 쓰세요. 천 단위 구분 기호는 넣지 않지만 폭과 부호를 제어합니다.
자주 묻는 질문
PHP에서 숫자에 콤마를 넣으려면 어떻게 하나요?
number_format($n)을 호출하세요: number_format(1234567)은 "1,234,567"을 반환합니다. 소수점 자리는 두 번째 인수로 넘기세요: number_format(1234567.891, 2)는 "1,234,567.89"를 반환합니다.
콤마 없이 number_format을 쓰려면 어떻게 하나요?
천 단위 구분 기호로 빈 문자열을 넘기세요: number_format(1234.5, 2, '.', '')는 "1234.50"을 반환합니다. 결제 API와 CSV 파일이 보통 기대하는 형태입니다.
number_format은 반올림하나요, 버리나요?
0에서 먼 쪽으로 반올림합니다: number_format(2.5)는 "3", number_format(-2.5)는 "-3", number_format(2.675, 2)는 "2.68"입니다. 소수점을 버리려면 먼저 floor()를 쓰세요: number_format(floor(2.679 * 100) / 100, 2)는 "2.67"을 줍니다.
숫자를 유럽식(1.234,56)으로 포맷하려면 어떻게 하나요?
세 번째와 네 번째 인수로 구분 기호를 바꾸세요: number_format(1234.56, 2, ',', '.')는 "1.234,56"을 반환합니다. 프랑스식과 스위스식은 네 번째 인수로 공백이나 아포스트로피를 씁니다.
number_format 결과에 더하면 잘못된 값이 나오는 이유는 무엇인가요?
number_format()은 "1,234.50" 같은 문자열을 반환하고, 그것으로 계산하면 PHP는 쉼표 앞의 1만 읽습니다. 계산에는 숫자를 그대로 두고 출력할 때만 number_format()을 호출하세요.