Laravel には多言語化を行う仕組みがあり、メッセージファイルに各文言を定義し、App::setLocale('ロケール文字列')で任意のロケールをセットして、メッセージをキーで都度呼び出すことでによって多言語化を実現します。
多言語化 8.x Laravel
メッセージファイルはresources/lang/ja/validation.phpの様に resource/lang 以下の各言語として用意します。最初から用意されている auth.php, pagination.php, passwords.php, validation.php については特に迷うことなくそれを使えばよいのですが、自由にメッセージファイルを入れるとなると悩みどころです。この記事ではこれはありなのではないかと考えている整理方法を紹介します。
私的にメッセージファイルで重要なことはどこで何が使われているか追いやすいこと、定義の重複したメッセージがないことです。メッセージを使っているクラスを名前空間付きのキーでまとめることによってこれらを実現します(適切な使いまわしも大事なのですが、いい感じの方法が見つかりません。固有名詞の辞書とか?)。具体的には次の様にします。
<?php
/** /resources/lang/ja/class.php 定義例 */
return [
App\Exceptions\Handler::class => [
'msg' => ':modelが見つかりませんでした。',
],
App\Http\Controllers\Web\Account\AccountDeleteController::class => [
'success' => 'アカウントを削除しました。',
'failed' => 'アカウントの削除に失敗しました。',
],
/**
* メッセージがさらに続きます
*/
];
<?php
/** app/Http/Controllers/Web/Account/AccountDeleteController.php 使用例 */
namespace App\Http\Controllers\Web\Account;
use App\Exceptions\AppPermissionDeniedException;
use App\Http\Controllers\Web\WebBaseController;
use App\Http\HttpStatus;
use App\Models\Eloquents\Account;
use App\UseCase\Account\Actions\DeleteAction;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpKernel\Exception\HttpException;
class AccountDeleteController extends WebBaseController
{
public function delete(DeleteAction $action, $accountId): JsonResponse
{
/** @var Account $account */
$account = Account::findOrFail($accountId);
try {
// 削除成功したら success メッセージ
// 削除失敗したら failed メッセージを返します
return $action($deleteTgt, $this->loginAccount())
? $this->sendSuccess(trans('class.' . self::class . '.success'))
: $this->sendError(trans('class.' . self::class . '.failed'));
} catch (AppPermissionDeniedException $exception) {
throw new HttpException(HttpStatus::FORBIDDEN, $exception->getMessage());
}
}
}
このようにクラス単位でメッセージを定義すると、キーの衝突についてはクラスの中でのみ考ればよく、後から追うのもクラスを追うだけで済みます。
’class.’ . を毎度書くのは面倒ですし typo の元です。次の様なヘルパー関数を作るとさらに楽でき、ミスが減ります。
if (! function_exists('trans_class')) {
/**
* resources/lang/xx/class.php に定義した class の namespace で区切った言語メッセージを読み込む.
*
* @param string $class self::class など、クラス名フルパス
* @param string $key クラス以下に置いたキー
* @param array $replace trans にパス
* @param string|null $locale trans にパス
* @return string
*/
function trans_class(string $class, string $key, array $replace = [], ?string $locale = null): string
{
// ↓の形式はクラス以下にはフラットな配列要素しか置かない代わりに、キーに"."を使えるようにしたコードです
return \Arr::get(trans('class.'.$class, $replace, $locale), $key) ?? '';
// キーに"."を使えない代わりにクラス以下に多次元配列を定義できる様にするならば次のように書きます
// return trans('class.'.$class . '.' . $key, $replace, $locale) ?? '';
}
}