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

Yii2多语言URL路由问题:如何为Action URL添加多语言支持?

Yii2 多语言URL路由的便捷实现方案

嘿,我完全懂你的痛点——手动给每个Action配置多语言路由太繁琐了,尤其是未来还要加更多语言,那工作量简直不敢想。好在Yii2原生就有一套高效的方案,不用逐个绑定控制器,就能实现你要的那种多语言URL效果,下面一步步给你讲清楚:

核心思路:自定义URL规则+翻译系统联动

我们要做的是让路由里的固定片段(比如category/categoria)通过翻译系统自动映射,动态的slug(比如chair/silla)从数据库取对应语言的值,同时用自定义URL规则类统一处理路由的生成和解析,避免重复劳动。

1. 先确保你的i18n组件配置到位

首先得保证翻译系统能正常工作,在config/web.php里的components下配置好i18n:

'components' => [
    'i18n' => [
        'translations' => [
            '*' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@app/messages',
                'sourceLanguage' => 'en', // 源语言设为英文
                'fileMap' => [
                    'app' => 'app.php', // 核心翻译文件
                ],
            ],
        ],
    ],
    // 其他组件配置...
],

然后在messages目录下创建对应语言的翻译文件,比如西班牙语的messages/es/app.php:

return [
    'category' => 'categoria',
    // 未来加其他需要翻译的路由片段,比如'product' => 'producto',直接加这里
];

2. 编写自定义URL规则类

这个类的作用是自动把URL里的翻译片段转成源语言的路由(解析请求),以及把源语言路由转成当前语言的翻译片段(生成URL)。在app/components下创建I18nUrlRule.php:

namespace app\components;

use yii\web\UrlRule;
use Yii;

class I18nUrlRule extends UrlRule
{
    public $translations = []; // 存储需要翻译的路由片段和对应的翻译分类

    // 解析请求:把URL里的翻译片段转成源语言路由
    public function parseRequest($manager, $request)
    {
        $pathInfo = $request->getPathInfo();
        $parts = explode('/', $pathInfo);

        // 遍历替换每个路由片段为源语言键
        foreach ($parts as $key => $part) {
            foreach ($this->translations as $sourceKey => $category) {
                // 用源语言反向查找翻译对应的键
                $reverseTrans = Yii::t($category, $sourceKey, [], 'en');
                if ($part === $reverseTrans) {
                    $parts[$key] = $sourceKey;
                    break;
                }
            }
        }

        $request->setPathInfo(implode('/', $parts));
        return parent::parseRequest($manager, $request);
    }

    // 生成URL:把源语言路由转成当前语言的翻译片段
    public function createUrl($manager, $route, $params)
    {
        $url = parent::createUrl($manager, $route, $params);

        // 替换路由里的源语言键为当前语言的翻译
        foreach ($this->translations as $sourceKey => $category) {
            $translated = Yii::t($category, $sourceKey);
            $url = str_replace($sourceKey, $translated, $url);
        }

        return $url;
    }
}

3. 配置URL管理器使用自定义规则

在config/web.php的urlManager里添加这个自定义规则,这样就能批量处理多语言路由了:

'urlManager' => [
    'enablePrettyUrl' => true,
    'showScriptName' => false,
    'rules' => [
        [
            'class' => 'app\components\I18nUrlRule',
            'pattern' => '<category>/<slug>',
            'route' => 'category/slug',
            'translations' => [
                'category' => 'app', // 告诉规则:category这个片段用app翻译文件里的内容
            ],
        ],
        // 未来加其他类似路由,比如product/slug,直接复制这个规则改参数就行
    ],
],

4. 处理动态slug的多语言存储

你例子里的chair/silla是动态分类别名,这部分不能用翻译文件,得存在数据库里。比如给你的category表加slug_en、slug_es字段(未来加新语言就加对应字段),然后在分类模型里加个方法获取当前语言的slug:

// Category模型里的方法
public function getCurrentSlug()
{
    $currentLang = Yii::$app->language;
    $slugField = "slug_{$currentLang}";
    return $this->$slugField ?? $this->slug_en; // fallback到英文
}

5. 生成和解析URL的正确姿势

  • 生成URL:在视图或控制器里用Yii的URL助手,结合模型的方法:
// 比如获取某个分类的URL
$categoryUrl = Url::to([
    'category/slug',
    'category' => 'category', // 这里用源语言的键,自定义规则会自动转成当前语言的翻译
    'slug' => $category->getCurrentSlug()
]);
// 西班牙语环境下会生成 /categoria/silla
  • 解析URL:在CategoryController的actionSlug里,你拿到的$category参数已经是源语言的category(因为自定义规则已经帮你转好了),然后根据当前语言查询对应的slug:
public function actionSlug($category, $slug)
{
    $currentLang = Yii::$app->language;
    $categoryModel = Category::find()
        ->where(["slug_{$currentLang}" => $slug])
        ->one();

    if (!$categoryModel) {
        throw new \yii\web\NotFoundHttpException('分类不存在');
    }

    // 后续业务逻辑...
}

未来扩展的便捷性

当你要加新语言(比如法语)时,只需要做3件事:

  1. 添加messages/fr/app.php翻译文件,补充路由片段的翻译(比如category => catégorie)。
  2. 给category表加slug_fr字段,存入对应语言的别名。
  3. 不需要修改任何路由规则,自定义规则会自动处理新语言的路由生成和解析。

这样就完全不用手动给每个Action绑定控制器了,一套规则搞定所有同类路由,非常省心。

内容的提问来源于stack exchange,提问作者Chico3001

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:43:25