cable8mm / n-format
Laravel package for Korean and Japanese number formatting with Eloquent casts, value objects, ordinal support, currency formatting, and smart price rounding
Requires
- php: ^8.2
- ext-intl: *
- illuminate/contracts: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^10.11.0|^11.2.0
- phpunit/phpunit: ^10.0|^11.0|^12.0
Suggests
- laravel/pint: Provides fixing all codes for coding style
This package is auto-updated.
Last update: 2026-08-24 08:55:27 UTC
README
Laravel 애플리케이션에서 숫자, 통화, 퍼센트, 서수 표현을 일관되게 다루기 위한 PHP 패키지입니다. PHP의 NumberFormatter를 확장한 NFormat API와 함께 Laravel 서비스 프로바이더, 설정 파일, Eloquent 캐스트, 불변 값 객체를 제공합니다.
v2부터 N-Format은 NFormat 클래스 하나만 제공하던 래퍼에서 Laravel 통합을 포함하는 패키지로 확장되었습니다.
요구 사항
- PHP 8.2 이상
intlPHP 확장- Laravel 12 또는 13
설치
composer require cable8mm/n-format
Laravel의 패키지 자동 검색을 지원하므로 별도로 서비스 프로바이더를 등록할 필요가 없습니다.
설정
기본 설정은 한국어·대한민국 원화입니다.
// config/n-format.php return [ 'locale' => 'ko_KR', 'currency' => 'KRW', ];
설정 파일이 필요하면 애플리케이션으로 게시합니다.
php artisan vendor:publish --tag=n-format
게시한 설정은 모든 NFormat 메서드와 값 객체의 기본값으로 사용됩니다. 특정 호출에서 로케일이나 통화를 직접 전달하여 기본값을 덮어쓸 수도 있습니다.
기본 사용법
use Cable8mm\NFormat\NFormat; NFormat::currency(358762); // ₩358,762 NFormat::decimal(12346); // 12,346 NFormat::spellOut(5); // 오 NFormat::ordinalSpellOut(10); // 열번째 NFormat::currencySpellOut(12346); // 12,346 원 NFormat::percent(12346); // 1,234,600% NFormat::rawPercent(12346); // 12,346%
percent()는 입력값에 100을 곱하고, rawPercent()는 입력값을 100으로 나눈 뒤 퍼센트로 표시합니다.
PHP 8.2 이상에서는 파라미터 이름을 지정하는 named arguments도 사용할 수 있습니다. 긴 호출에서 각 값의 의미를 명확하게 표현할 수 있습니다.
NFormat::currency( number: 12346, zero: '-', locale: 'ja_JP', currency: 'JPY', ); // ¥12,346 NFormat::price(number: 12346, roundDigits: -2); // 12300
메서드 파라미터 이름은 공개 API의 일부이므로, named arguments를 사용하는 경우 파라미터 이름 변경에 주의해야 합니다.
호출별로 로케일과 통화를 지정할 수 있습니다.
NFormat::$locale = 'ja_JP'; NFormat::spellOut(5); // 五 NFormat::currency(12346, '0', 'ja_JP', 'JPY'); // ¥12,346
currency()의 두 번째 인자는 0 또는 null일 때 사용할 대체 문자열입니다. 세 번째와 네 번째 인자가 각각 로케일과 통화입니다.
가격 반올림
price()는 지정한 자릿수로 반올림하고, smartPrice()는 통화 드라이버의 규칙에 따라 자릿수별로 반올림합니다.
NFormat::price(12346, -2); // 12300 NFormat::smartPrice(12346); // 12300 NFormat::smartPrice(1234678); // 1230000
기본 KRW 규칙은 다음과 같습니다.
- 1~2자리: 반올림하지 않음
- 3자리: 10의 자리
- 4~5자리: 100의 자리
- 6자리: 1,000의 자리
- 7자리 이상: 10,000의 자리
Eloquent 캐스트
v2는 Eloquent 속성을 불변 값 객체로 변환하는 두 가지 캐스트를 제공합니다.
AsCurrency:Money값 객체 반환AsNumber:Number값 객체 반환
use Cable8mm\NFormat\Casts\AsCurrency; use Cable8mm\NFormat\Casts\AsNumber; use Illuminate\Database\Eloquent\Model; class Product extends Model { protected function casts(): array { return [ 'price' => AsCurrency::class, 'jpy' => AsCurrency::class.':ja_JP,JPY', 'discount' => AsNumber::class, 'count' => AsNumber::class.':ja_JP', ]; } }
읽을 때는 값 객체가 반환되고, 저장할 때는 통화 기호와 천 단위 구분자를 제거한 숫자만 데이터베이스에 저장됩니다.
$product = new Product; $product->price = '₩12,350원'; echo $product->price; // 12350 (raw value) echo $product->price->currency(); // ₩12,350 echo $product->price->price(-2); // 12400 echo $product->price->smartPrice(); // 12400 echo $product->price->spellOut(); // 12,350 원 echo $product->price->value(); // 12350
금액이 0이면 통화 기호 대신 번역된 무료 문구를 표시합니다.
$product->price = 0; echo $product->price; // 0 (raw value) echo $product->price->currency(); // 무료
기본 번역은 한국어 무료, 영어 Free, 일본어 無料이며, AsCurrency에 지정한 로케일을 기준으로 선택합니다. 번역 파일은 다음 명령으로 게시할 수 있습니다.
php artisan vendor:publish --tag=n-format-translations
번역 키는 n-format::messages.free입니다.
Number는 기본적으로 천 단위 구분자를 사용해 출력합니다.
$product->discount = 12346; echo $product->discount; // 12,346 echo $product->discount->percent(); // 1,234,600% echo $product->discount->rawPercent(); // 12,346% echo $product->discount->spellOut(); // 일만이천삼백사십육 echo $product->discount->ordinalSpellOut(); // 열번째 echo $product->discount->value(); // 12346
두 값 객체는 Stringable, JsonSerializable을 구현합니다. 문자열로 출력하면 포맷된 값을 사용하고, JSON으로 직렬화하면 원시 숫자를 사용합니다.
Blade에서도 그대로 사용할 수 있습니다.
{{ $product->price }} {{ $product->discount->percent() }}
숫자·통화 캐스트는 숫자와 포맷된 숫자 문자열을 저장할 수 있습니다. null, 빈 문자열, 숫자로 변환할 수 없는 값은 null로 저장되거나 읽힙니다.
드라이버 확장
로케일별 서수 표현과 통화별 가격 규칙은 드라이버로 분리되어 있습니다. 다음 인터페이스를 구현한 뒤 등록하면 지원 범위를 확장할 수 있습니다.
use Cable8mm\NFormat\Drivers\Contracts\OrdinalDriver; final class EnUsOrdinalDriver implements OrdinalDriver { public function spellOut(int $number): string { return match ($number) { 1 => 'first', 2 => 'second', default => $number.'th', }; } } NFormat::registerOrdinal('en_US', new EnUsOrdinalDriver); NFormat::ordinalSpellOut(2, 'en_US'); // second
통화 드라이버는 currencySpellOut()과 roundDigits()를 구현합니다.
use Cable8mm\NFormat\Drivers\Contracts\CurrencyDriver; final class UsdCurrencyDriver implements CurrencyDriver { public function currencySpellOut(string $formatted): string { return $formatted.' dollars'; } public function roundDigits(): array { return [3 => -1, 4 => -2, 5 => -2]; } } NFormat::registerCurrency('USD', new UsdCurrencyDriver);
기본 제공 드라이버는 ko_KR 서수 표현과 KRW 통화 규칙입니다. 등록되지 않은 드라이버를 요청하면 ordinalSpellOut()과 currencySpellOut()은 NumberFormatter의 기본 결과를 반환합니다.
API
| 메서드 | 설명 |
|---|---|
spellOut(int, ?string) |
숫자를 단어로 변환 |
ordinalSpellOut(int, ?string) |
서수 표현 |
currency(int|float|null, string, ?string, ?string) |
통화 포맷 |
currencySpellOut(int|float, ?string, ?string) |
통화와 단어를 함께 표시 |
decimal(int|float|null, string, ?string) |
천 단위 구분자 포맷 |
percent(int|float, ?string) |
100을 곱한 퍼센트 |
rawPercent(int|float, ?string) |
100으로 나눈 퍼센트 |
price(int|float, ?int) |
지정 자릿수 반올림 |
smartPrice(int|float, ?string) |
통화 규칙에 따른 반올림 |
registerOrdinal(string, OrdinalDriver) |
로케일 드라이버 등록 |
registerCurrency(string, CurrencyDriver) |
통화 드라이버 등록 |
개발
composer install composer test # PHPUnit 테스트 composer inspect # 코드 스타일 검사 composer check # 스타일 검사와 테스트 composer lint # 코드 스타일 자동 수정
라이선스
N-Format은 MIT 라이선스로 제공됩니다.