本文目录导读:

在 PHP 项目中实现本地化(i18n),主要有 5 种主流方案,根据项目规模和需求选择:
gettext 扩展(最专业,适合大型项目)
这是 Linux 系统最标准的本地化方案,支持复数、上下文等复杂语法。
// 1. 初始化
putenv('LANG=zh_CN.utf8');
setlocale(LC_ALL, 'zh_CN.utf8');
bindtextdomain('messages', './locale');
textdomain('messages');
// 2. 使用
echo gettext("Hello World");
// 或短函数
echo _("Hello World");
准备翻译文件:
- 需要安装
gettext工具生成.po和.mo文件 - 结构:
./locale/zh_CN/LC_MESSAGES/messages.mo
优点:性能最好,支持复数规则
缺点:需要服务器安装 gettext 扩展,配置文件较复杂
数组/JSON 文件(最简单,适合中小项目)
最常用的轻量级方案,把翻译放在 PHP 数组或 JSON 文件中。
// lang/zh.php
return [
'welcome' => '欢迎光临',
'hello' => '你好,:name',
'items_count' => '{0} 没有项目|{1} 一个项目|[2,*] :count 个项目',
];
// 使用
$translations = require "lang/{$lang}.php";
echo $translations['welcome']; // 欢迎光临
// 动态替换
$name = 'John';
echo str_replace(':name', $name, $translations['hello']);
最优实践:封装成类
class Translator {
private $translations = [];
public function __construct($lang) {
$this->translations = require "lang/{$lang}.php";
}
public function trans($key, $params = []) {
$text = $this->translations[$key] ?? $key;
foreach ($params as $k => $v) {
$text = str_replace(":{$k}", $v, $text);
}
return $text;
}
// 支持复数
public function transChoice($key, $count, $params = []) {
$rules = explode('|', $this->translations[$key]);
// 简单的复数逻辑
$index = $count == 1 ? 1 : 2;
$text = $rules[$index] ?? $rules[0];
return str_replace(':count', $count, $text);
}
}
使用第三方库(省时省力)
Symfony Translation 组件
composer require symfony/translation
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\PhpFileLoader;
$translator = new Translator('zh_CN');
$translator->addLoader('php', new PhpFileLoader());
$translator->addResource('php', __DIR__.'/lang/zh.php', 'zh_CN');
echo $translator->trans('welcome');
echo $translator->trans('items_count', ['%count%' => 5]);
Laravel 风格的简单实现
// 使用框架的 __() 函数
__('messages.welcome');
__('messages.order_count', ['count' => 5]);
数据库存储(适合动态内容)
适合需要在线修改翻译的场景。
CREATE TABLE translations (
id INT PRIMARY KEY AUTO_INCREMENT,
key VARCHAR(255) UNIQUE,
locale VARCHAR(10),
value TEXT
);
class DBTranslator {
private $cache = [];
public function trans($key, $locale = 'zh') {
if (!isset($this->cache[$locale])) {
// 加载该语言的所有翻译到缓存
$this->cache[$locale] = $this->loadFromDB($locale);
}
return $this->cache[$locale][$key] ?? $key;
}
}
现代框架自带方案
如果你在 Laravel / Symfony 等框架中,直接使用内置功能:
Laravel 示例
// 创建语言文件
// resources/lang/zh/messages.php
// 使用
echo __('messages.welcome');
echo trans_choice('messages.items', $count);
Symfony 示例
// translations/messages.zh_CN.yaml
// 使用
echo $this->translator->trans('welcome');
实战建议
✅ 推荐组合方案:
- 小项目:使用
数组/JSON+ 封装类 - 中大型项目:
gettext或Symfony Translation组件 - 框架项目:直接用框架内置 i18n
📁 目录结构建议:
project/
├── lang/
│ ├── zh.php
│ ├── en.php
│ └── fr.php
├── locale/ # gettext 文件
│ ├── zh_CN/LC_MESSAGES/messages.mo
│ └── en_US/LC_MESSAGES/messages.mo
└── src/
└── Translator.php
🎯 最佳实践:
- 语言检测:根据
Accept-Language或用户选择 - 语言包缓存:使用 APCu/Redis 缓存翻译数据
- 翻译键规范:使用
模块.功能.具体操作格式(user.login.success) - 占位符统一:统一使用
param格式
选择适合你项目规模的方案,复杂度越高收益越大,小项目别过度设计!
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播