laminas/laminas-translator
Laminas Translator provides message translation for PHP apps, supporting multiple locales, pluralization, and translation files like gettext and PHP arrays. Includes adapters, loaders, and integration helpers to localize UI text cleanly across modules.
Installation:
composer require laminas/laminas-translator
First Use Case:
Laminas\Translator\TranslatorInterface in your service or controller:
use Laminas\Translator\TranslatorInterface;
class MyService {
public function __construct(private TranslatorInterface $translator) {}
}
Laminas\I18n\Translator\Translator) without coupling to laminas-i18n.Where to Look First:
TranslatorInterface source: Laminas/Translator/TranslatorInterface.php.Dependency Injection:
$app->bind(TranslatorInterface::class, function ($app) {
return new \Laminas\I18n\Translator\Translator();
});
TranslatorFactory.Translation Logic:
$translator->translate('Hello, %name!', ['name' => 'World']);
messages, validation):
$translator->translate('Invalid email', 'validation');
Adapter Integration:
Laminas\I18n\Translator\Adapter\Gettext or ArrayAdapter:
$adapter = new \Laminas\I18n\Translator\Adapter\ArrayAdapter([
'Hello' => 'Hola',
]);
$translator->addTranslationSource($adapter);
Locale Management:
$translator->setLocale('es_ES');
$translator->setLocale($request->getPreferredLanguage());
Facade Integration (Custom):
trans() helper:
class LaminasTranslatorFacade extends \Illuminate\Support\Facades\Facade {
protected static function getFacadeAccessor() {
return app(TranslatorInterface::class);
}
}
AppServiceProvider:
public function register() {
$this->app->singleton(TranslatorInterface::class, function () {
return new \Laminas\I18n\Translator\Translator();
});
}
View Integration:
@lang directive or use a custom Blade component:
Blade::directive('laminasLang', function ($expression) {
return "<?php echo app('translator')->translate($expression); ?>";
});
Usage:
@laminasLang('Hello')
Validation Messages:
$validator = Validator::make($data, $rules);
$validator->setTranslator(function ($message, $attribute, $rule, $parameters) {
return app(TranslatorInterface::class)->translate($message, 'validation');
});
Breaking Changes in 2.0.0:
TranslatorInterface now uses native parameter/return types (e.g., string translate(string $id, array $text = [], string $locale = null, string $domain = null)).__invoke) may break. Test thoroughly.No Laravel/Symfony Integration:
Low Community Support:
voku/translation, symfony/translation) if maintenance is a concern.Pluralization Quirks:
$translator->translatePlural(
'%count% item',
'%count% items',
$count,
'messages'
);
Adapter Conflicts:
Check Locale Fallbacks:
$translator->getLocale(); // Current locale
$translator->getFallbackLocale(); // Fallback chain
Inspect Translation Sources:
$sources = $translator->getTranslationSources();
print_r($sources);
Enable Debug Mode:
Translator, set:
$translator->setDebug(true);
Handle Missing Translations:
$translator->setDefaultTextDomain('messages');
$translator->setFallbackLocale('en_US');
Custom Adapters:
Laminas\I18n\Translator\Adapter\AdapterInterface for new translation sources (e.g., API-based translations):
class ApiTranslationAdapter implements AdapterInterface {
public function isEmpty(): bool { /* ... */ }
public function translate($message, $locale, $textDomain): string { /* ... */ }
}
Pluralization Rules:
Laminas\I18n\Translator\TextDomain\TextDomain:
class CustomTextDomain extends TextDomain {
protected function getPluralRule($locale): string {
return 'custom rule for ' . $locale;
}
}
Caching Layer:
Laminas\Cache):
$cache = new \Laminas\Cache\Storage\Adapter\Memory();
$translator = new \Laminas\I18n\Translator\Translator();
$cachedTranslator = new \Laminas\I18n\Translator\Translator\CachedTranslator($translator, $cache);
Laravel Service Provider:
AppServiceProvider to bind the translator with caching:
public function register() {
$this->app->singleton(TranslatorInterface::class, function ($app) {
$translator = new \Laminas\I18n\Translator\Translator();
$translator->setCache(new \Illuminate\Cache\Repository($app['cache']));
return $translator;
});
}
Text Domain Defaults:
DEFAULT_TEXT_DOMAIN constant ('default') may conflict with Laravel’s default domain ('messages'). Explicitly set domains:
$translator->translate('key', 'messages');
Locale Negotiation:
public function handle($request, Closure $next) {
app(TranslatorInterface::class)->setLocale($request->getPreferredLanguage());
return $next($request);
}
Adapter Priority:
$translator->addTranslationSource($primaryAdapter);
$translator->addTranslationSource($fallbackAdapter);
How can I help you explore Laravel packages today?