Laravel本地化需求:新增多国家语言与货币配置
嘿,我来帮你搞定Laravel里的这套本地化配置逻辑!咱们从配置到核心实现一步步来,保证完全匹配你的需求~
Laravel 多地区本地化实现方案
一、先明确需求对应规则
先把你的需求整理成清晰的规则表,方便后续编码时对照:
- 瑞士(CH):主语言德语(de),货币瑞士法郎(CHF)——默认访问优先触发此规则
- 土耳其(TR):主语言土耳其语(tr),货币土耳其里拉(TRY)
- 德国(DE)、奥地利(AT):主语言德语(de),货币欧元(EUR)
- 欧洲其他地区:主语言英语(en),货币欧元(EUR)
- 世界其他地区:主语言待配置(通过配置项灵活调整)
二、配置文件准备
首先咱们先把支持的语言和货币映射关系配置好,后续修改更方便:
1. 语言配置(config/app.php)
在文件里新增支持的语言列表,同时确保默认语言符合瑞士访问的需求:
return [ // ... 其他原有配置 'locale' => 'de', // 默认语言(对应瑞士默认访问) 'fallback_locale' => 'en', 'locales' => ['de', 'en', 'tr'], // 项目支持的所有语言集合 ];
2. 货币配置(新建 config/currencies.php)
专门维护地区与货币的映射,后续调整货币规则直接改这个文件就行:
return [ 'ch' => 'CHF', 'tr' => 'TRY', 'de' => 'EUR', 'at' => 'EUR', 'europe_other' => 'EUR', 'world_other' => null, // 待配置,后续可改为比如 'USD' 等目标货币 ];
三、核心逻辑:本地化中间件
Laravel的中间件是处理请求级本地化的最佳方式,咱们创建一个自定义中间件来实现规则判断:
1. 生成中间件
运行Artisan命令快速生成:
php artisan make:middleware LocalizationMiddleware
2. 编写中间件逻辑
打开 app/Http/Middleware/LocalizationMiddleware.php,替换handle方法及添加辅助方法:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; class LocalizationMiddleware { public function handle(Request $request, Closure $next) { // 优先使用用户手动选择的本地化设置(存在session中) $locale = Session::get('locale'); $currency = Session::get('currency'); if (!$locale || !$currency) { // 获取用户所在国家代码(提供两种实现方式,选一种就行) $countryCode = strtolower($this->getUserCountryCode($request)); // 根据国家代码匹配对应的语言和货币 [$locale, $currency] = $this->matchLocalizationRules($countryCode); // 将设置存入session,避免每次请求都重复解析IP Session::put([ 'locale' => $locale, 'currency' => $currency ]); } // 设置应用当前使用的语言 app()->setLocale($locale); return $next($request); } /** * 获取用户所在国家代码 * 方式1:使用torann/geoip扩展(推荐,稳定可靠) * 方式2:调用免费IPAPI接口(需处理缓存和异常) */ private function getUserCountryCode(Request $request): string { // 方式1:使用torann/geoip(先安装:composer require torann/geoip) // return \Torann\GeoIP\Facades\GeoIP::getLocation($request->ip())->iso_code ?? 'ch'; // 方式2:调用免费IPAPI(示例,建议添加缓存避免频繁请求) $ip = $request->ip(); $response = @file_get_contents("http://ip-api.com/json/{$ip}"); $data = json_decode($response, true); return $data['countryCode'] ?? 'ch'; } /** * 根据国家代码匹配本地化规则 */ private function matchLocalizationRules(string $countryCode): array { // 欧洲国家代码集合(可根据业务需求补充更多国家) $europeanCountries = [ 'fr', 'es', 'it', 'nl', 'be', 'pt', 'se', 'dk', 'fi', 'no', 'pl', 'cz' ]; switch ($countryCode) { case 'ch': return ['de', config('currencies.ch')]; case 'tr': return ['tr', config('currencies.tr')]; case 'de': case 'at': return ['de', config('currencies.de')]; default: if (in_array($countryCode, $europeanCountries)) { return ['en', config('currencies.europe_other')]; } else { // 世界其他地区,使用配置的待设置语言(默认用fallback_locale) $defaultLocale = config('app.fallback_locale'); return [$defaultLocale, config('currencies.world_other')]; } } } }
3. 注册中间件
打开 app/Http/Kernel.php,将中间件添加到web中间件组(因为需要依赖session功能):
protected $middlewareGroups = [ 'web' => [ // ... 其他原有中间件 \App\Http\Middleware\LocalizationMiddleware::class, ], // ... ];
四、货币与视图集成
为了在视图中方便使用当前货币,咱们可以在服务提供者中把货币变量共享给所有视图:
打开 app/Providers/AppServiceProvider.php,在boot方法添加:
use Illuminate\Support\Facades\View; use Illuminate\Support\Facades\Session; public function boot() { // 共享当前货币到所有视图 View::share('current_currency', Session::get('currency') ?? config('currencies.ch')); }
之后在视图里就可以直接用 {{ $current_currency }} 显示当前货币符号/代码了。
五、用户手动切换功能(可选)
如果需要让用户手动切换语言和货币,可以添加一个简单的切换功能:
1. 添加路由
在 routes/web.php 中:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Session; Route::post('/localization/switch', function (Request $request) { // 验证参数合法性 $validated = $request->validate([ 'locale' => 'required|in:'.implode(',', config('app.locales')), 'currency' => 'required|in:CHF,TRY,EUR', // 根据项目支持的货币调整 ]); // 更新session中的本地化设置 Session::put([ 'locale' => $validated['locale'], 'currency' => $validated['currency'] ]); return back()->with('success', '本地化设置已更新'); })->name('localization.switch');
2. 视图切换组件示例
在视图中添加一个简单的切换表单:
<form action="{{ route('localization.switch') }}" method="POST"> @csrf <select name="locale"> <option value="de" {{ session('locale') == 'de' ? 'selected' : '' }}>Deutsch</option> <option value="en" {{ session('locale') == 'en' ? 'selected' : '' }}>English</option> <option value="tr" {{ session('locale') == 'tr' ? 'selected' : '' }}>Türkçe</option> </select> <select name="currency"> <option value="CHF" {{ session('currency') == 'CHF' ? 'selected' : '' }}>CHF</option> <option value="EUR" {{ session('currency') == 'EUR' ? 'selected' : '' }}>EUR</option> <option value="TRY" {{ session('currency') == 'TRY' ? 'selected' : '' }}>TRY</option> </select> <button type="submit">切换</button> </form>
六、测试与调整
- 可以通过浏览器插件模拟不同地区的IP,测试各个规则是否正确触发
- 世界其他地区的主语言可以通过修改
config/currencies.php里的world_other或者调整中间件里的默认值来配置 - 注意IP解析的准确性,推荐使用成熟的GeoIP扩展(如torann/geoip),免费接口可能存在请求限制和准确性问题
内容的提问来源于stack exchange,提问作者vanful
相关产品推荐
相关产品推荐

