本文目录导读:

我来详细介绍PHP多语言方案的几种主流实现方式:
使用Gettext扩展(最推荐)
安装配置
// 检查gettext是否可用
if (function_exists('gettext')) {
echo "Gettext已启用";
}
// 设置语言环境
putenv('LANG=zh_CN.UTF-8');
setlocale(LC_ALL, 'zh_CN.UTF-8');
// 指定domain(翻译文件的标识)
$domain = 'messages';
bindtextdomain($domain, './locale');
bind_textdomain_codeset($domain, 'UTF-8');
textdomain($domain);
使用示例
// 代码中直接使用英文,通过翻译文件转换
echo _("Hello World");
echo gettext("Welcome to our website");
echo _("Hello, %s!").sprintf($name);
创建翻译文件(.po/.mo)
# messages.po
msgid "Hello World"
msgstr "你好,世界"
msgid "Welcome to our website"
msgstr "欢迎访问我们的网站"
数组映射方案(轻量级)
<?php
class Translator {
private $translations = [];
private $defaultLang = 'zh';
public function __construct($lang = null) {
$this->load($lang ?? $this->detectLang());
}
public function load($lang) {
$file = __DIR__ . "/lang/{$lang}.php";
if (file_exists($file)) {
$this->translations = require $file;
}
}
public function t($key, $params = []) {
$text = $this->translations[$key] ?? $key;
// 参数替换
foreach ($params as $k => $v) {
$text = str_replace("{{$k}}", $v, $text);
}
return $text;
}
private function detectLang() {
// 从URL参数、Session或Cookie中检测
$available = ['zh', 'en', 'ja'];
$lang = $_GET['lang'] ?? $_SESSION['lang'] ??
($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'zh');
// 简单的语言检测逻辑
if (strpos($lang, 'zh') !== false) return 'zh';
if (strpos($lang, 'ja') !== false) return 'ja';
return 'en';
}
}
// 语言文件 lang/zh.php
return [
'welcome' => '欢迎光临',
'hello' => '你好,{:name}',
'login' => '登录',
'logout' => '退出'
];
// 使用方法
$translator = new Translator();
echo $translator->t('welcome');
echo $translator->t('hello', ['name' => '张三']);
JSON翻译文件方案
<?php
class JsonTranslator {
private $translations = [];
private $lang;
public function __construct($lang = 'zh') {
$this->lang = $lang;
$this->loadTranslations();
}
private function loadTranslations() {
$file = __DIR__ . "/lang/{$this->lang}.json";
if (file_exists($file)) {
$this->translations = json_decode(file_get_contents($file), true);
}
}
public function translate($key, $params = []) {
$text = $this->translations[$key] ?? $key;
// 支持占位符替换
preg_match_all('/\{(\w+)\}/', $text, $matches);
foreach ($matches[1] as $param) {
if (isset($params[$param])) {
$text = str_replace("{" . $param . "}", $params[$param], $text);
}
}
return $text;
}
public function setLang($lang) {
$this->lang = $lang;
$this->loadTranslations();
}
}
// JSON翻译文件 zh.json
{
"welcome": "欢迎光临",
"today": "今天是{today}",
"goodbye": "再见"
}
// 使用
$translator = new JsonTranslator('zh');
echo $translator->translate('welcome');
echo $translator->translate('today', ['today' => '星期一']);
完整的多语言框架实现
<?php
class I18n {
private static $instance;
private $lang;
private $translations = [];
private $fallbackLang = 'en';
private function __construct() {
$this->lang = $this->detectLanguage();
$this->load();
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function detectLanguage() {
// 优先级:参数 > Session > Cookie > 浏览器
if (isset($_GET['lang'])) {
return $this->sanitize($_GET['lang']);
}
if (isset($_SESSION['lang'])) {
return $this->sanitize($_SESSION['lang']);
}
if (isset($_COOKIE['lang'])) {
return $this->sanitize($_COOKIE['lang']);
}
// 浏览器语言检测
$browserLang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en', 0, 2);
return $this->sanitize($browserLang);
}
private function sanitize($lang) {
$available = ['zh', 'en', 'ja', 'fr', 'de'];
return in_array($lang, $available) ? $lang : 'en';
}
public function load() {
$file = __DIR__ . "/lang/{$this->lang}.php";
if (file_exists($file)) {
$this->translations = require $file;
}
}
public function setLang($lang) {
$this->lang = $this->sanitize($lang);
$this->load();
// 保存到Session/Cookie
$_SESSION['lang'] = $this->lang;
setcookie('lang', $this->lang, time() + 3600*24*30);
}
public function t($key, $params = []) {
$text = $this->translations[$key] ??
$this->translations[$this->fallbackLang][$key] ??
$key;
// 替换变量
foreach ($params as $k => $v) {
$text = str_replace(":{$k}", $v, $text);
$text = str_replace("{{$k}}", $v, $text);
}
return $text;
}
// 复数形式支持
public function plural($singular, $plural, $count) {
return $count == 1 ? $singular : $plural;
}
}
// 全局辅助函数
if (!function_exists('t')) {
function t($key, $params = []) {
return I18n::getInstance()->t($key, $params);
}
}
// 使用
echo t('welcome');
echo t('hello', ['name' => 'John']);
echo t('cart_item', ['count' => 5]);
文件结构布局
project/
├── lang/
│ ├── zh.php
│ ├── en.php
│ ├── ja.php
│ └── locale/
│ ├── zh_CN/
│ ├── en_US/
│ └── ja_JP/
├── config/
│ └── i18n.php
├── src/
│ ├── I18n.php
│ └── Translator.php
└── index.php
最佳实践建议
- 性能优化:使用缓存机制(文件缓存、Redis等)
- 命名规范:使用一致的key命名规则
- 版本控制:使用专门的翻译管理平台(如Lokalise, Crowdin)
- 动态语言切换:提供语言切换界面
- 测试:确保所有语言都有完善测试
补充:使用第三方库
// Symfony Translation组件
use Symfony\Component\Translation\Translator;
$translator = new Translator('zh_CN');
$translator->addLoader('php', new PhpFileLoader());
$translator->addResource('php', '/path/to/messages.php', 'zh_CN');
echo $translator->trans('hello_world');
// Laravel的多语言
@lang('messages.welcome')
选择哪种方案取决于:
- 项目规模数量
- 是否需要复数处理
- 团队技术栈
- 性能要求
推荐小型项目使用数组映射,中型项目使用JSON方案,大型项目使用Gettext或专业框架。