本文目录导读:

我来详细介绍PHP实现语言包(国际化/i18n)的几种常用方法:
最简单的数组方式
基础实现
<?php
// lang/en.php
return [
'welcome' => 'Welcome to our website',
'hello' => 'Hello, :name',
'login' => 'Login',
'logout' => 'Logout',
];
// lang/zh.php
return [
'welcome' => '欢迎访问我们的网站',
'hello' => '你好,:name',
'login' => '登录',
'logout' => '退出',
];
使用类封装
<?php
class Translator {
private static $translations = [];
private static $defaultLang = 'zh';
public static function load($lang) {
$file = __DIR__ . "/lang/{$lang}.php";
if (file_exists($file)) {
self::$translations = require $file;
}
}
public static function setLang($lang) {
self::load($lang);
}
public static function t($key, $params = []) {
$text = self::$translations[$key] ?? $key;
// 替换参数
foreach ($params as $name => $value) {
$text = str_replace(":{$name}", $value, $text);
}
return $text;
}
}
// 使用示例
Translator::setLang($_GET['lang'] ?? 'zh');
echo Translator::t('welcome'); // 欢迎访问我们的网站
echo Translator::t('hello', ['name' => '张三']); // 你好,张三
使用Gettext扩展
安装配置
// php.ini 中开启 extension=gettext // 创建翻译文件目录 // locale/zh_CN/LC_MESSAGES/messages.po
Gettext使用示例
<?php
// 初始化gettext
function initGettext($lang = 'zh_CN') {
$locale = $lang . '.UTF-8';
putenv("LANG={$locale}");
setlocale(LC_ALL, $locale);
$domain = 'messages';
bindtextdomain($domain, __DIR__ . '/locale');
textdomain($domain);
}
// 使用gettext
initGettext('zh_CN');
echo gettext("Welcome to our website");
echo _("Hello, World!"); // _() 是 gettext() 的简写
// 带变量的翻译
printf(_("Hello, %s"), '张三');
PO文件示例
# locale/zh_CN/LC_MESSAGES/messages.po msgid "Welcome" msgstr "欢迎" msgid "Hello, %s" msgstr "你好,%s"
使用第三方库 - Symfony Translation
安装
composer require symfony/translation
使用示例
<?php
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\Loader\PhpFileLoader;
$translator = new Translator('zh_CN');
// 添加加载器
$translator->addLoader('php', new PhpFileLoader());
$translator->addLoader('array', new ArrayLoader());
// 加载翻译文件
$translator->addResource('php', __DIR__ . '/lang/zh.php', 'zh_CN');
$translator->addResource('php', __DIR__ . '/lang/en.php', 'en');
// 使用翻译
echo $translator->trans('welcome');
echo $translator->trans('hello', ['%name%' => '张三']);
// 复数形式
echo $translator->trans('apple', ['%count%' => 5], 'messages', 'zh_CN');
完整的语言包管理系统
<?php
class LanguageManager {
private $langDir;
private $currentLang;
private $translations = [];
private static $instance = null;
private function __construct() {
$this->langDir = __DIR__ . '/lang/';
$this->currentLang = $this->detectLanguage();
$this->loadLanguage();
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function detectLanguage() {
// 从会话获取
if (isset($_SESSION['lang'])) {
return $_SESSION['lang'];
}
// 从Cookie获取
if (isset($_COOKIE['lang'])) {
return $_COOKIE['lang'];
}
// 从浏览器语言自动检测
$browserLang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '', 0, 2);
return in_array($browserLang, ['zh', 'en']) ? $browserLang : 'zh';
}
public function setLanguage($lang) {
if (file_exists($this->langDir . $lang . '.php')) {
$this->currentLang = $lang;
$_SESSION['lang'] = $lang;
setcookie('lang', $lang, time() + 3600 * 24 * 365);
$this->loadLanguage();
}
}
private function loadLanguage() {
$file = $this->langDir . $this->currentLang . '.php';
$this->translations = file_exists($file) ? require $file : [];
}
public function t($key, $params = []) {
$text = $this->translations[$key] ?? $key;
if (!empty($params)) {
foreach ($params as $name => $value) {
$text = preg_replace('/\{' . $name . '\}|:' . $name . '/i', $value, $text);
}
}
return $text;
}
public function getCurrentLang() {
return $this->currentLang;
}
public function getAllTranslations() {
return $this->translations;
}
}
// 使用示例
$lang = LanguageManager::getInstance();
echo $lang->t('welcome'); // 自动检测语言并翻译
echo $lang->t('hello', ['name' => '李四']);
语言切换功能
<?php
// 语言切换链接
$currentLang = LanguageManager::getInstance()->getCurrentLang();
?>
<div class="language-switcher">
<a href="?lang=zh" <?php echo $currentLang == 'zh' ? 'class="active"' : ''; ?>>中文</a>
<a href="?lang=en" <?php echo $currentLang == 'en' ? 'class="active"' : ''; ?>>English</a>
</div>
<?php
// 处理切换请求
if (isset($_GET['lang'])) {
$allowed = ['zh', 'en', 'ja', 'fr'];
$requested = $_GET['lang'];
if (in_array($requested, $allowed)) {
LanguageManager::getInstance()->setLanguage($requested);
header('Location: ' . str_replace('?lang=' . $requested, '', $_SERVER['REQUEST_URI']));
}
}
数据库存储语言包
<?php
class DatabaseTranslator {
private $db;
private $translations = [];
public function __construct($pdo) {
$this->db = $pdo;
$this->loadTranslations();
}
public function loadTranslations($lang) {
$stmt = $this->db->prepare("
SELECT t.key, t.value
FROM translations t
WHERE t.language = :lang
");
$stmt->execute(['lang' => $lang]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$this->translations[$row['key']] = $row['value'];
}
}
public function t($key) {
return $this->translations[$key] ?? $key;
}
// 缓存翻译到文件
public function cacheToFile($lang) {
$cacheFile = __DIR__ . "/cache/{$lang}.php";
$content = "<?php\nreturn " . var_export($this->translations, true) . ";\n";
file_put_contents($cacheFile, $content);
}
}
最佳实践建议
- 命名规范:使用点号分隔层级,如
menu.home.title - 参数化:避免拼接字符串,使用占位符
- 缓存机制:生产环境可以合并缓存语言文件
- 自动检测:根据用户浏览器语言自动选择
- 回退机制:找不到翻译时返回原始键名
选择哪种方案取决于项目需求:
- 简单项目用数组方式
- 需要系统级支持用Gettext
- 大型项目用Symfony等成熟库
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播