Laravel 5.4:如何在控制器中控制多语言数据库内容输出
在Laravel控制器中处理多语言事件描述的最佳实践
嘿,我来帮你把多语言内容的控制逻辑从Blade视图移到控制器(甚至更优的模型层),让代码更符合MVC的最佳实践~
核心思路
把语言判断、内容提取的逻辑从视图中剥离,集中到控制器或模型里,让视图只负责纯粹的渲染工作,这样不仅代码更整洁,也方便后续维护和复用。
方法一:在控制器中处理逻辑
首先,我们可以利用Laravel自带的本地化工具获取当前语言,然后遍历数据,为每个事件提取对应语言的描述(还可以添加 fallback 逻辑,避免空内容)。
修改你的控制器代码如下:
public function mafia() { // 获取当前应用的语言标识(比如 'ru'、'lv'、'en') $currentLocale = app()->getLocale(); // 定义允许的语言列表,和你的数据表字段对应 $allowedLocales = ['ru', 'lv', 'en']; // 确保当前语言在允许范围内,否则 fallback 到默认语言(这里用英文) if (!in_array($currentLocale, $allowedLocales)) { $currentLocale = 'en'; } // 查询所有游戏数据,并处理每个数据的描述字段 $games = Mafiagame::all()->map(function ($game) use ($currentLocale) { // 提取当前语言的描述 $description = $game->{$currentLocale}; // 如果当前语言的描述为空,自动 fallback 到英文 if (empty($description)) { $description = $game->en; } // 给游戏对象添加一个统一的 `description` 属性,方便视图调用 $game->description = $description; return $game; }); return view('your-view-path', compact('games')); }
之后你的Blade视图就可以简化成直接调用统一的属性,不用再写语言判断:
@foreach($games as $game) <div> <p>{{ $game->datetime }}</p> <p>{{ $game->description }}</p> </div> @endforeach
方法二:用模型访问器(更推荐的最佳实践)
如果这个多语言描述的逻辑在多个地方都需要用到,把它放到模型里会更优雅,符合“胖模型瘦控制器”的原则。
在你的 Mafiagame 模型中添加一个访问器:
/** * 获取当前语言对应的事件描述 */ public function getDescriptionAttribute() { $currentLocale = app()->getLocale(); $allowedLocales = ['ru', 'lv', 'en']; // 校验语言合法性 if (!in_array($currentLocale, $allowedLocales)) { $currentLocale = 'en'; } // 优先取当前语言的内容,为空则 fallback 到英文 $description = $this->{$currentLocale}; return empty($description) ? $this->en : $description; }
这时你的控制器会变得非常简洁:
public function mafia() { $games = Mafiagame::all(); return view('your-view-path', compact('games')); }
视图的调用方式和上面一样,直接用 {{ $game->description }} 即可。
为什么这是最佳实践?
- 职责分离:视图只负责渲染,控制器负责数据查询,模型负责数据的业务处理,符合MVC设计模式
- 代码复用:如果其他控制器或视图需要同样的多语言逻辑,直接用模型的访问器就行,不用重复写判断
- 易于维护:如果后续要修改语言规则(比如新增语言、调整fallback逻辑),只需要修改模型或控制器的一处代码即可
内容的提问来源于stack exchange,提问作者Karlis Pokkers
相关产品推荐
相关产品推荐

