You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:43:50