Source strings as keys, like gettext. ICU formatting for plurals
and gender, like Symfony's translator. Plain PHP arrays — no
.po, no parsing.
The global t() alias is registered at autoload time.
If t() is already defined, a notice is issued and you
use \phrazor\t() directly. Both signatures are identical.
// No vars — returns translation or pattern
t('Welcome');
// Variable substitution — ICU syntax
t('Welcome, {name}', [
'name' => $name,
]);
// Namespaced form — always available
\phrazor\t('Welcome, {name}', [
'name' => $name,
]);
// Plural
t('{count, plural,
=0 {No items}
one {# item}
other {# items}
}', ['count' => $n]);
// Gender / select
t('{gender, select,
male {He liked this}
female {She liked this}
other {They liked this}
}', ['gender' => $g]);
Each locale file returns a PHP array. The source pattern is the key, the translation is the value. ICU patterns — including multiline pluralization and gender blocks — are valid as both keys and values. If a pattern has no translation, the pattern itself is returned.
return [
'Welcome' => 'Bienvenue',
'Welcome, {name}' =>
'Bienvenue, {name}',
'{count, plural,
=0 {No items}
one {# item}
other {# items}
}' =>
'{count, plural,
=0 {Aucun élément}
one {# élément}
other {# éléments}
}',
];
en_US requires no locale file. If a pattern has no entry, the pattern itself is the translation. Your source code is already the English copy.
Multiline patterns are supported as keys — phrazor does not normalize or reformat them. Write the pattern however you write it in source and use it as-is in the locale file.
Locale files are plain required PHP — no parsing,
no deserialization. The result is cached in memory for the
lifetime of the process.
| Constant | Purpose | Default |
|---|---|---|
| PHRAZOR_I18N_PATH | Directory containing locale files. | i18n/ |
| PHRAZOR_LOCALE | Active locale identifier. | en_US |
| PHRAZOR_MISSING_LOCALE | Behaviour when a locale file is not found: error, warn, or silent. |
warn / silent |
Locale resolution order:
When PHRAZOR_MISSING_LOCALE is not set, phrazor warns
when APP_DEBUG is truthy and falls back silently in production.
The scanner crawls your source files, extracts every pattern passed
to t(), and diffs against your existing locale files —
adding new keys, flagging removed ones, leaving existing translations
untouched.
# Scan using phrazor.php in project root
vendor/bin/phrazor scan
# Specify locales
vendor/bin/phrazor scan \
--locale=fr_FR,de_DE \
--output=verbose
# Custom function aliases
vendor/bin/phrazor scan \
--functions=t,_,trans
# Identity mappings for new keys
vendor/bin/phrazor scan --identity
return [
'i18n_path' => __DIR__ . '/i18n',
'source' => [__DIR__ . '/src'],
'locales' => ['fr_FR', 'de_DE'],
'functions' => ['t', '_'],
'scan' => [
'removed' => 'comment',
'new_keys' => 'bottom',
'sort' => false,
'identity' => false,
'output' => 'summary',
],
];
New key placement options:
Uses token_get_all() — not regex. Multiline patterns,
heredocs, and nowdocs are extracted correctly. Dynamic patterns
such as t($var) or t('a' . $b) are skipped
with a warning showing file and line number.
New keys are written as // TODO: comments so translators
know what needs attention. Removed keys are commented out rather
than deleted, preserving translations if a key returns.