本文目录导读:

在 PHP 中实现本地化(i18n,即国际化)主要有以下几种方法,从简单到复杂:
使用 gettext 扩展(最标准)
安装配置
# Ubuntu/Debian sudo apt-get install php-gettext gettext # Windows 需要在 php.ini 中启用 extension=php_gettext.dll
实现示例
<?php
// 设置语言环境
$locale = 'zh_CN'; // 或者 'en_US', 'fr_FR' 等
putenv("LANG=$locale");
setlocale(LC_ALL, $locale);
// 指定翻译文件目录
bindtextdomain('messages', './locale');
bind_textdomain_codeset('messages', 'UTF-8');
textdomain('messages');
// 使用翻译函数
echo _("Hello World"); // 将根据语言环境显示翻译内容
echo gettext("Welcome"); // 同上
创建翻译文件
# 1. 创建 po 文件 xgettext -n -o locale/zh_CN/LC_MESSAGES/messages.po source.php # 2. 编辑 po 文件添加翻译 # 3. 编译为 mo 文件 msgfmt -o locale/zh_CN/LC_MESSAGES/messages.mo messages.po
使用数组/配置文件(简单方案)
<?php
class Translator {
private $lang = 'zh_CN';
private $translations = [];
public function __construct($lang = 'zh_CN') {
$this->lang = $lang;
$this->loadTranslations();
}
private function loadTranslations() {
$file = "lang/" . $this->lang . ".php";
if (file_exists($file)) {
$this->translations = include $file;
}
}
public function translate($key) {
return isset($this->translations[$key])
? $this->translations[$key] : $key;
}
public function __call($name, $args) {
if ($name === 't') {
return $this->translate($args[0]);
}
}
}
// 语言文件 lang/zh_CN.php
return [
'hello' => '你好',
'welcome' => '欢迎',
'goodbye' => '再见',
// 带参数的情况
'greeting' => '您好, %s!',
];
// 使用示例
$tr = new Translator('zh_CN');
echo $tr->t('hello'); // 输出: 你好
printf($tr->t('greeting'), '张三'); // 输出: 您好, 张三!
使用 JSON 文件(推荐)
<?php
class I18n {
private static $instance = null;
private $translations = [];
private $lang;
private function __construct($lang = 'zh') {
$this->lang = $lang;
$this->load();
}
public static function getInstance($lang = null) {
if ($lang === null) {
$lang = isset($_SESSION['lang']) ? $_SESSION['lang'] : 'zh';
}
if (self::$instance === null || self::$instance->lang !== $lang) {
self::$instance = new self($lang);
}
return self::$instance;
}
private function load() {
$file = "lang/{$this->lang}.json";
if (file_exists($file)) {
$this->translations = json_decode(file_get_contents($file), true);
}
}
public function t($key, $params = []) {
$text = isset($this->translations[$key])
? $this->translations[$key] : $key;
foreach ($params as $k => $v) {
$text = str_replace('{' . $k . '}', $v, $text);
}
return $text;
}
public function getLang() {
return $this->lang;
}
}
?>
<!-- lang/zh.json -->
{
"hello": "你好",
"welcome": "欢迎来到我们的网站",
"greeting": "您好, {name}!",
"cart_items": "购物车中有 {count} 件商品"
}
<!-- 使用示例 -->
<?php
$i18n = I18n::getInstance($_SESSION['lang']);
echo $i18n->t('hello'); // 你好
echo $i18n->t('greeting', ['name' => '张三']); // 您好, 张三!
echo $i18n->t('cart_items', ['count' => 3]); // 购物车中有 3 件商品
?>
使用 Composer 库
推荐几个流行的库:
# Symfony Translation 组件 composer require symfony/translation # 或者使用 simpler 的 php-array-translator composer require php-array-translator/translator
Symfony Translation 示例
<?php
require 'vendor/autoload.php';
use Symfony\Component\Translation\Translator;
use Symfony\Component\Translation\Loader\ArrayLoader;
$translator = new Translator('zh_CN');
$translator->addLoader('array', new ArrayLoader());
$translator->addResource('array', [
'hello' => '你好',
'welcome' => '欢迎访问'
], 'zh_CN');
echo $translator->trans('hello'); // 你好
完整的本地化实现示例
<?php
class Localization {
private $lang;
private $data;
public function __construct() {
$this->detectLanguage();
$this->loadLanguageData();
}
private function detectLanguage() {
// 1. 检查 URL 参数
if (isset($_GET['lang'])) {
$this->lang = $_GET['lang'];
$_SESSION['lang'] = $this->lang;
}
// 2. 检查 Session
elseif (isset($_SESSION['lang'])) {
$this->lang = $_SESSION['lang'];
}
// 3. 检查 Cookie
elseif (isset($_COOKIE['lang'])) {
$this->lang = $_COOKIE['lang'];
}
// 4. 检查浏览器语言
else {
$browserLang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en', 0, 2);
$this->lang = in_array($browserLang, ['zh', 'en', 'fr']) ? $browserLang : 'en';
}
}
private function loadLanguageData() {
$file = __DIR__ . "/lang/{$this->lang}.json";
$this->data = file_exists($file) ?
json_decode(file_get_contents($file), true) : [];
}
public function lang() {
return $this->lang;
}
public function __invoke($key, $params = []) {
$text = $this->data[$key] ?? $key;
foreach ($params as $k => $v) {
$text = str_replace('{' . $k . '}', $v, $text);
}
return $text;
}
// 添加语言切换方法
public function switchLanguage($lang) {
$_SESSION['lang'] = $lang;
setcookie('lang', $lang, time() + 3600*24*30);
$this->lang = $lang;
$this->loadLanguageData();
}
}
// 使用
$t = new Localization();
echo $t('hello');
echo $t('greeting', ['name' => 'John']);
高级技巧
复数形式处理
function plural($n, $forms) {
// 英文复数规则
if ($forms[1] && $n != 1) return $forms[1];
// 中文没有复数形式
return $forms[0];
}
// 使用
echo sprintf(plural($count, ['%d item', '%d items']), $count);
动态语言切换 HTML
<!-- 语言切换器 --> <a href="?lang=zh">中文</a> | <a href="?lang=en">English</a> | <a href="?lang=fr">Français</a>
最佳实践建议
- 使用统一函数名:如
t()或 - 分离语言文件:每个语言一个 JSON 文件
- 使用缓存:缓存加载的语言文件
- 错误处理:找不到翻译时返回原始键名
- 编码统一:使用 UTF-8 编码
选择哪种方案取决于项目需求:
- 小型项目:使用 JSON 文件方案
- 中型项目:使用 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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播