核心原理
这个系统的核心思想是 “前后端分离”,但又紧密结合:

- 前端 (jQuery):负责 检测用户语言偏好 和 动态替换页面文本,它不关心翻译文件具体内容,只负责根据一个“语言代码”(如
en,zh-CN)去请求和替换。 - 后端 (PHP):负责 管理所有翻译内容(存储在数组或文件中)和 提供默认语言,当用户第一次访问或未指定语言时,PHP 根据浏览器信息提供默认语言。
数据流简图:
[用户访问网站]
|
v
[PHP 检测浏览器语言, 加载默认翻译文件]
|
v
[PHP 将默认语言代码 (如 'en') 传递给前端 (通过 HTML data-attribute)]
|
v
[前端 (jQuery) 接收语言代码]
|
v
[jQuery 加载对应的 JSON 翻译文件]
|
v
[jQuery 遍历页面, 替换所有带有特定属性的文本]
|
v
[用户看到多语言页面]
|
v
[用户点击切换语言 (如 'zh-CN')]
|
v
[jQuery 重新加载对应的 JSON 翻译文件并替换文本]
第一步:PHP 后端准备
PHP 的主要任务是提供一个“语言包”和默认语言。
创建语言文件
我们使用 PHP 数组来存储翻译,因为它简单直观,然后我们将这些数组转换成 JSON 格式,方便 jQuery 直接使用。
创建一个目录 languages/,然后在里面创建不同语言的文件:

languages/en.php (英文)
<?php
return [
'welcome' => 'Welcome to our website!',
'about' => 'About Us',
'contact' => 'Contact',
'language_switch' => 'Switch to Chinese'
];
languages/zh-CN.php (简体中文)
<?php
return [
'welcome' => '欢迎来到我们的网站!',
'about' => '关于我们',
'contact' => '联系我们',
'language_switch' => '切换到英文'
];
创建一个语言加载器 (get_language.php)
这个文件是前后端交互的桥梁,它根据请求的 lang 参数,返回对应的 JSON 翻译内容。
get_language.php

<?php
header('Content-Type: application/json; charset=utf-8');
// 1. 定义可用语言
$availableLanguages = ['en', 'zh-CN'];
// 2. 确定要加载的语言
// 优先使用 URL 参数 (?lang=zh-CN),其次使用浏览器首选项
$lang = isset($_GET['lang']) ? $_GET['lang'] : substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 5);
// 3. 验证语言是否有效
if (!in_array($lang, $availableLanguages)) {
// 如果无效,使用默认语言 (例如英语)
$lang = 'en';
}
// 4. 构建文件路径并加载
$langFile = __DIR__ . '/languages/' . $lang . '.php';
if (file_exists($langFile)) {
// 包含文件并获取返回的数组
$translations = include $langFile;
// 将 PHP 数组编码为 JSON 字符串并输出
echo json_encode($translations, JSON_UNESCAPED_UNICODE);
} else {
// 文件不存在,返回空对象或错误
echo json_encode(['error' => 'Language file not found']);
}
说明:
header('Content-Type: ...')告诉浏览器我们返回的是 JSON 数据,并使用 UTF-8 编码,避免中文乱码。$_SERVER['HTTP_ACCEPT_LANGUAGE']是一个包含用户浏览器首选项语言的字符串(zh-CN,zh;q=0.9,en;q=0.8),我们用substr取前5位zh-CN。include $langFile会执行 PHP 文件,而include $langFile会获取return的值,这正是我们想要的。
在主页面中嵌入默认语言
在你的主 HTML 文件中,我们需要告诉 jQuery 默认使用哪种语言。
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">多语言网站</title>
<!-- ... 其他 head 内容 ... -->
</head>
<body>
<h1 data-i18n="welcome">Welcome to our website!</h1>
<nav>
<a href="#" data-i18n="about">About Us</a>
<a href="#" data-i18n="contact">Contact</a>
</nav>
<button id="lang-switcher" data-i18n="language_switch">Switch to Chinese</button>
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 将默认语言通过 data 属性传递给 JavaScript -->
<script>
var defaultLang = '<?php echo substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 5); ?>';
// 为了确保语言有效,可以在这里做一次校验,或者直接让 PHP 后端 get_language.php 来做
// 为了简单,我们直接传递,让 JS 来处理
</script>
<script src="js/i18n.js"></script> <!-- 我们下一步创建这个文件 -->
</body>
</html>
注意: 我们给所有需要翻译的文本元素都添加了一个 data-i18n 属性,它的值就是我们在 PHP 语言文件中定义的“键”(key)。
第二步:jQuery 前端实现
现在我们来创建 js/i18n.js 文件,这是实现动态切换语言的核心。
js/i18n.js
$(document).ready(function() {
// 1. 初始化
// 从 HTML script 标签中获取默认语言,或者使用 'en' 作为后备
let currentLang = $('script').last().data('default-lang') || 'en';
// 2. 翻换函数
function translatePage(lang) {
// 显示加载提示(可选)
// $('body').css('opacity', '0.8');
// AJAX 请求获取翻译文件
$.ajax({
url: 'get_language.php',
type: 'GET',
data: { lang: lang },
dataType: 'json',
success: function(translations) {
// 遍历所有带有 data-i18n 属性的元素
$('[data-i18n]').each(function() {
let key = $(this).data('i18n');
// 如果在翻译文件中找到了对应的键
if (translations[key]) {
// 替换元素的文本内容
// $(this).text(translations[key]);
// 更好的做法:同时替换 HTML 属性,title, placeholder, alt 等
// 这里我们只替换文本内容
$(this).text(translations[key]);
}
});
// 更新当前语言状态
currentLang = lang;
// 存储用户选择到 localStorage,下次访问时记住
localStorage.setItem('user_lang', lang);
// 恢复页面(可选)
// $('body').css('opacity', '1');
},
error: function(xhr, status, error) {
console.error("Error loading language file: " + error);
// 可以在这里显示一个错误提示
}
});
}
// 3. 页面加载时执行翻译
// 首先检查 localStorage 中是否有用户之前选择的语言
let userSavedLang = localStorage.getItem('user_lang');
if (userSavedLang) {
translatePage(userSavedLang);
} else {
// 如果没有,则使用默认语言(从 PHP 传递过来的)
translatePage(currentLang);
}
// 4. 语言切换按钮点击事件
$('#lang-switcher').on('click', function(e) {
e.preventDefault(); // 阻止链接的默认跳转行为
let newLang;
if (currentLang === 'en') {
newLang = 'zh-CN';
} else {
newLang = 'en';
}
translatePage(newLang);
});
});
第三步:整合与测试
-
目录结构:
/your-project/ ├── index.php ├── get_language.php ├── languages/ │ ├── en.php │ └── zh-CN.php └── js/ └── i18n.js -
测试流程:
- 打开
index.php,页面应该根据你的浏览器语言显示英文或中文。 - 点击 "Switch to Chinese" 或 "切换到英文" 按钮,页面内容应立即切换。
- 刷新页面,页面应保持你最后选择的语言(因为
localStorage记住了它)。 - 清除浏览器缓存和
localStorage,刷新页面,应回到基于浏览器语言的初始状态。
- 打开
进阶与最佳实践
处理 HTML 属性
有些文本不在标签之间,而是在 title, placeholder, alt 等属性中,我们可以扩展 translatePage 函数来处理这些。
修改 js/i18n.js 中的遍历部分:
// 在 translatePage 函数的 success 回调中
$('[data-i18n]').each(function() {
let key = $(this).data('i18n');
if (translations[key]) {
// 替换文本内容
$(this).text(translations[key]);
// 替换其他属性
// 假设我们在 HTML 中这样写: <input type="text" data-i18n-placeholder="username_placeholder">
if ($(this).data('i18n-placeholder')) {
$(this).attr('placeholder', translations[$(this).data('i18n-placeholder')]);
}
// 同理可以处理 data-i18n-title 等
}
});
然后在你的 HTML 中:
<input type="text" data-i18n-placeholder="username_placeholder">
在语言文件中:
// en.php 'username_placeholder' => 'Enter your username', // zh-CN.php 'username_placeholder' => '请输入您的用户名',
更优雅的语言切换
不要用简单的 if/else 来切换,可以维护一个映射对象。
// 在 i18n.js 顶部
const langMap = {
'en': 'zh-CN',
'zh-CN': 'en'
};
// 在点击事件处理函数中
let newLang = langMap[currentLang];
translatePage(newLang);
使用 URL 重写实现 SEO 友好的链接 (example.com/en/about)
这是一个更高级的方案,需要服务器配置 (如 Apache 的 .htaccess 或 Nginx 的 rewrite 规则)。
- 原理: 当用户访问
/en/about时,服务器将其重写为index.php?lang=en&page=about,PHP 根据lang和page参数加载对应的语言和页面内容。 - 优点: 对搜索引擎非常友好,每个语言版本都有一个独立的 URL。
- 缺点: 实现起来更复杂,需要服务器端配合。
使用专业的 PHP 国际化库
如果你的项目非常大,可以考虑使用成熟的库,如 Symfony/Translation 或 Zend/I18n,它们提供了更强大的功能,如:
- 复数形式处理 (e.g., 1 apple vs. 2 apples)
- 区域特定格式化 (日期、数字)
- 消息占位符 (e.g., "Hello %name%, your balance is %amount%$")
- 翻译缓存机制
对于中小型项目,我们上面介绍的“手写”方案已经足够高效和灵活。
通过 PHP 提供翻译数据 和 jQuery 负责前端动态渲染 的方式,你可以快速构建一个功能完善、易于维护的多语言网站,这个方案的优点是:
- 轻量: 不需要引入庞大的框架。
- 灵活: 翻译文件是纯 PHP,可以轻松集成到你的现有项目中。
- 用户体验好: 切换语言是即时的,无需刷新整个页面。
- 可扩展: 可以方便地添加更多语言和更复杂的翻译逻辑。
