i18n — Message Catalog¶
Nene\Func\I18n is a lightweight, dependency-free message-catalog helper that provides locale-aware string translation with {placeholder} substitution.
When to use¶
Use I18n when you need to:
- Return user-facing messages in more than one language
- Keep translatable strings out of controller logic
- Substitute dynamic values (user name, counts, etc.) into translated messages
For large, complex projects consider a dedicated i18n library. I18n is intentionally minimal.
API¶
| Method | Description |
|---|---|
I18n::setLocale(string $locale): void |
Set the default locale used when no locale is passed to t(). |
I18n::locale(): string |
Get the current default locale (default: 'en'). |
I18n::load(string $locale, array $messages): void |
Register (or merge) a key→message map for the locale. |
I18n::t(string $key, array $params = [], string $locale = ''): string |
Look up and substitute a message. |
I18n::reset(): void |
Clear all catalogs and restore defaults. Use in test tearDown. |
Registering messages¶
Call load() once at bootstrap (e.g. in ini/xSystemIni.php or a controller's preAction()):
I18n::setLocale('ja');
I18n::load('ja', [
'greeting' => 'こんにちは、{name}さん!',
'item.count' => '{count}件あります',
'error.auth' => '認証が必要です',
]);
I18n::load('en', [
'greeting' => 'Hello, {name}!',
'item.count' => '{count} item(s) found',
'error.auth' => 'Authentication required',
]);
Calling load() twice with the same locale merges the arrays (later keys win).
Translating¶
// Uses the current default locale ('ja')
echo I18n::t('greeting', ['name' => '太郎']);
// → こんにちは、太郎さん!
// Explicit locale override
echo I18n::t('greeting', ['name' => 'Taro'], 'en');
// → Hello, Taro!
// No params needed for static strings
echo I18n::t('error.auth');
// → 認証が必要です
Placeholder syntax¶
Placeholders are written as {key} and replaced by the matching key in $params:
I18n::load('en', ['msg' => 'Dear {title} {last},']);
echo I18n::t('msg', ['title' => 'Dr.', 'last' => 'Smith']);
// → Dear Dr. Smith,
- Unknown placeholders are left as-is (not removed).
- A key may appear multiple times in one message.
Fallback chain¶
- Requested locale (or default locale when no locale argument is given).
- Default locale, if different from the requested one.
- The key string itself when no translation is found.
I18n::setLocale('en');
I18n::load('en', ['hello' => 'Hello!']);
// 'ja' has no 'hello' → falls back to 'en'
echo I18n::t('hello', [], 'ja'); // → Hello!
// Completely unknown key → key returned as-is
echo I18n::t('no.such.key'); // → no.such.key
Locale naming¶
Any string is accepted as a locale identifier. Common conventions:
| Identifier | Use |
|---|---|
'en' |
English |
'ja' |
Japanese |
'zh-TW' |
Traditional Chinese |
'fr' |
French |
Use a consistent convention across your project.
Testing¶
Call I18n::reset() in tearDown() to prevent catalog state from leaking between tests:
Organising catalogs¶
For larger projects, keep catalogs in dedicated PHP files:
Load at bootstrap:
I18n::setLocale($userLocale);
I18n::load('ja', require __DIR__ . '/../resources/lang/ja.php');
I18n::load('en', require __DIR__ . '/../resources/lang/en.php');
Related¶
Nene\Func\Validator— input validation with translatable error messages.config/error_codes.php— framework-level error messages (not translated throughI18n, returned as-is in the JSON envelope).