Laravel 11 本地化 & 通过中间件实现多语言国际化
本篇文章将演示如何在 Laravel 11 应用中使用本地化来实现多语言支持。
Laravel Localization 可以实现将应用程序内容翻译成不同的语言,并在各种语言之间进行切换,从而实现多语言切换。
以下案例将实现中文、英文、法语、意大利语之间的切换。
安装项目
创建项目时,选择 Laravel Breeze
$ laravel new local
$ cd local
发布语言文件
1)生成语言文件
$ php artisan lang:publish
该命令会在 app
目录生成 lang
目录和相关语言文件。
2)定义语言文件
lang/en/messages.php
<?php
return [
"users" => "Users",
"users_list" => "Users Listing",
"dashboard" => "Dashboard",
"dashboard_message" => "You're logged in!"
];
lang/fr/messages.php
<?php
return [
"users" => "Utilisateurs",
"users_list" => "Liste des utilisateurs",
"dashboard" => "Tableau de bord",
"dashboard_message" => "Vous êtes connecté!"
];
lang/it/messages.php
<?php
return [
"users" => "Utenti",
"users_list" => "Elenco degli utenti",
"dashboard" => "Pannello di controllo",
"dashboard_message" => "Hai effettuato l'accesso!"
];
lang/zh_CN/messages.php
<?php
return [
"users" => "用户",
"users_list" => "用户列表",
"dashboard" => "面板",
"dashboard_message" => "面板消息!"
];
创建中间件
这一步最为关键,需要在中间件中检查语言并进行设置。
1)生成中间件
$ php artisan make:middleware SetLocale
2)中间件处理逻辑
app/Http/Middleware/SetLocale.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Symfony\Component\HttpFoundation\Response;
class SetLocale
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// 检查会话中是否存在 'locale' 设置
if($request->session()->has('locale')){
// 设置应用程序的语言环境为会话中存储的值,默认为 'zh_CN'
App::setLocale($request->session()->get('locale', 'zh_CN'));
}
return $next($request);
}
}
3)注册中间件
bootstrap/app.php
<?php
use App\Http\Middleware\SetLocale;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
// 注册中间件
$middleware->web(append: [
SetLocale::class
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();
添加路由
routes/web.php
<?php
use App\Http\Controllers\LanguageController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\UserController;
use Illuminate\Support\Facades\Route;
...
Route::middleware('auth')->group(function () {
...
Route::get('lang', [LanguageController::class, 'change'])->name("change.lang");
Route::get('users', [UserController::class, 'index'])->name('users.index');
});
require __DIR__.'/auth.php';
创建控制器
1)生成控制器
$ php artisan make:controller LanguageController
$ php artisan make:controller UserController
2)编写控制器方法
app/Http/Controllers/LanguageController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class LanguageController extends Controller
{
/**
* 更改应用的语言设置
*
* @param Request $request
* @return RedirectResponse
*/
public function change(Request $request): RedirectResponse
{
$lang = $request->input('lang', 'zh_CN');
if (!in_array($lang, ['zh_CN','en', 'it', 'fr'])) {
abort(400);
}
Session::put('locale', $lang);
return redirect()->back();
}
}
app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\View\View;
class UserController extends Controller
{
/**
* 用户列表
*
* @return View
*/
public function index(): View
{
return view("users");
}
}
创建并更新视图文件
resources/views/layouts/navigation.blade.php
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100">
...
<!-- Settings Dropdown -->
<div class="hidden sm:flex sm:items-center sm:ms-6">
<x-dropdown align="right" width="48">
<x-slot name="trigger">
<button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
@php($languages = ['en' => 'English', 'fr' => 'French', 'it' => 'Italian','zh_CN'=>'中国'])
<div>选择语言: {{ $languages[Session::get('locale', 'en')] }}</div>
<div class="ms-1">
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</div>
</button>
</x-slot>
<x-slot name="content">
<x-dropdown-link :href="route('change.lang', ['lang' => 'zh_CN'])">
中文
</x-dropdown-link>
<x-dropdown-link :href="route('change.lang', ['lang' => 'en'])">
English
</x-dropdown-link>
<x-dropdown-link :href="route('change.lang', ['lang' => 'fr'])">
French
</x-dropdown-link>
<x-dropdown-link :href="route('change.lang', ['lang' => 'it'])">
Italian
</x-dropdown-link>
</x-slot>
</x-dropdown>
...
</div>
...
</nav>
resources/views/dashboard.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('messages.dashboard') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100">
{{ __("messages.dashboard_message") }}
</div>
</div>
</div>
</div>
</x-app-layout>
resources/views/users.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
{{ __('messages.users') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100">
{{ __('messages.users_list') }}
</div>
</div>
</div>
</div>
</x-app-layout>
启动服务并测试
$ php artisan serve
现在,注册一个用户并进行登录,之后就可以选择语言进行切换了。
请登录后再评论