yiisoft/translator-message-php
PHP message source for Yii Translator that loads translations from PHP files/arrays. Provides a simple, fast backend for storing and retrieving localized messages, suitable for Yii apps needing file-based i18n without a database.
Installation
composer require yiisoft/translator-message-php
Add to composer.json under autoload:
"autoload": {
"psr-4": {
"App\\Messages\\": "path/to/messages/"
}
}
Basic Message Definition
Create a PHP file (e.g., app/Messages/Welcome.php):
<?php
namespace App\Messages;
use Yiisoft\Translator\Message\Message;
return new Message([
'en-US' => 'Welcome, {name}!',
'es-ES' => '¡Bienvenido, {name}!',
]);
First Usage
use Yiisoft\Translator\Message\MessageFactory;
$factory = new MessageFactory();
$welcome = $factory->createFromFile(__DIR__ . '/Messages/Welcome.php');
echo $welcome->get('en-US', ['name' => 'John']); // "Welcome, John!"
Yiisoft\Translator\Message\Message for translation keys, placeholders, and metadata.Yiisoft\Translator\Message\MessageFactory for loading messages from files or arrays.Yiisoft\Translator\Message\MessageInterface for expected methods (e.g., get(), has()).Message Organization
Auth/Welcome.php, Auth/Login.php).Messages/en-US/Welcome.php, Messages/es-ES/Welcome.php) for large projects.Message constructor:
return new Message([
'en-US' => 'Default',
'es-ES' => null, // Fallback to 'en-US'
], 'en-US');
Dynamic Loading
$message = $factory->createFromFile($path);
$this->view->render('page', ['message' => $message->get($locale, $params)]);
Message objects in a service container or Redis:
$cacheKey = "message:{$locale}:{$filePath}";
$message = $cache->get($cacheKey) ?? $factory->createFromFile($filePath);
$cache->set($cacheKey, $message, 3600);
Integration with Laravel
public function register()
{
$this->app->bind(MessageFactory::class, function () {
return new MessageFactory();
});
}
View::composer('*', function ($view) {
$view->with('welcome', app(MessageFactory::class)->createFromFile(...));
});
Validation Messages
$validator = Validator::make($data, $rules);
$validator->setMessages([
'email' => app(MessageFactory::class)->createFromFile(...),
]);
MessageInterface for project-specific methods (e.g., getPlural()).MessageFactory in unit tests:
$mockFactory = Mockery::mock(MessageFactory::class);
$mockFactory->shouldReceive('createFromFile')->andReturn($message);
$this->app->instance(MessageFactory::class, $mockFactory);
Locale Fallbacks
$message->get('fr-FR'); // Throws \InvalidArgumentException if 'fr-FR' is missing.
Message constructor or handle exceptions:
try {
echo $message->get($locale, $params);
} catch (\InvalidArgumentException $e) {
echo $message->get($defaultLocale, $params);
}
File Caching
Message objects (see Dynamic Loading above).Placeholder Conflicts
{name} vs. {name} in nested messages) can cause parsing errors.Message::validatePlaceholders().Namespace Collisions
return new Message([...], 'App\Messages\Welcome');
Message::validate() to check for syntax errors:
if (!$message->validate()) {
throw new \RuntimeException('Invalid message format');
}
get() calls in a try-catch to log unsupported locales:
try {
$translation = $message->get($locale);
} catch (\InvalidArgumentException $e) {
\Log::warning("Missing translation for locale: {$locale}");
$translation = $message->get($defaultLocale);
}
Custom Message Formats
Message to support JSON/YAML:
class JsonMessage extends Message
{
public static function fromJson(string $json): self
{
$data = json_decode($json, true);
return new self($data['translations'], $data['defaultLocale'] ?? null);
}
}
Pluralization
class PluralMessage extends Message
{
public function getPlural(string $locale, int $count): string
{
$key = $this->getKey($locale, $count);
return $this->get($locale, ['count' => $count]);
}
}
Message Compilation
use Yiisoft\Translator\Message\MessageCompiler;
$compiler = new MessageCompiler();
$compiler->compileDirectory(__DIR__ . '/Messages', __DIR__ . '/MessagesCompiled.php');
Message or handled globally (e.g., via Laravel’s App::setLocale()).chmod -R 755 path/to/messages).How can I help you explore Laravel packages today?