本文目录导读:

在PHP项目中实现语言包的加载和切换,常见的方式有以下几种,我会从简单到复杂,给出具体实现方案。
基础思路
语言包本质上是键值对存储,常见格式:
- PHP数组文件
- JSON文件
- INI文件
- 数据库存储
简单实现(PHP数组文件)
目录结构
project/
├── lang/
│ ├── zh_cn.php
│ ├── en.php
│ └── ja.php
├── includes/
│ └── language.php
└── index.php
语言文件示例
lang/zh_cn.php
<?php
return [
'welcome' => '欢迎光临',
'login' => '登录',
'logout' => '退出',
'hello' => '你好, :name',
'items_count' => '共有 :count 个项目'
];
lang/en.php
<?php
return [
'welcome' => 'Welcome',
'login' => 'Login',
'logout' => 'Logout',
'hello' => 'Hello, :name',
'items_count' => 'Total :count items'
];
语言加载类
includes/language.php
<?php
class Language {
private static $instance = null;
private $translations = [];
private $currentLang = 'zh_cn';
// 支持的语言列表
private $supportedLanguages = ['zh_cn', 'en', 'ja'];
private function __construct() {
$this->setLanguage($this->getBrowserLanguage());
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 设置当前语言
*/
public function setLanguage($lang) {
$lang = $this->sanitizeLanguage($lang);
$this->currentLang = $lang;
// 加载语言文件
$file = __DIR__ . '/../lang/' . $lang . '.php';
if (file_exists($file)) {
$this->translations = include $file;
} else {
// 默认加载中文
$this->translations = include __DIR__ . '/../lang/zh_cn.php';
}
}
/**
* 获取翻译文本
*/
public function get($key, $params = []) {
$text = isset($this->translations[$key])
? $this->translations[$key]
: $key; // 找不到返回key本身
// 替换参数
if (!empty($params)) {
foreach ($params as $key => $value) {
$text = str_replace(':' . $key, $value, $text);
}
}
return $text;
}
/**
* 获取浏览器首选语言
*/
private function getBrowserLanguage() {
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$preferred = substr($langs[0], 0, 5);
// 将浏览器语言映射到我们的语言代码
$map = [
'zh-CN' => 'zh_cn',
'zh-TW' => 'zh_tw',
'en-US' => 'en',
'en-GB' => 'en',
'ja-JP' => 'ja'
];
foreach ($map as $browser => $our) {
if (stripos($preferred, substr($browser, 0, 2)) !== false) {
return $our;
}
}
}
return 'zh_cn'; // 默认中文
}
/**
* 清理和验证语言代码
*/
private function sanitizeLanguage($lang) {
$lang = strtolower(str_replace('-', '_', $lang));
if (!in_array($lang, $this->supportedLanguages)) {
return 'zh_cn';
}
return $lang;
}
/**
* 获取当前语言
*/
public function getCurrentLanguage() {
return $this->currentLang;
}
}
// 辅助函数
function __($key, $params = []) {
return Language::getInstance()->get($key, $params);
}
使用示例
index.php
<?php
require_once 'includes/language.php';
// 初始化语言
$lang = Language::getInstance();
// 手动切换语言(例如通过URL参数)
if (isset($_GET['lang'])) {
$_SESSION['lang'] = $_GET['lang'];
$lang->setLanguage($_GET['lang']);
} elseif (isset($_SESSION['lang'])) {
$lang->setLanguage($_SESSION['lang']);
}
// 在模板中使用
?>
<!DOCTYPE html>
<html>
<head><?php echo __('welcome'); ?></title>
</head>
<body>
<h1><?php echo __('welcome'); ?></h1>
<p><?php echo __('hello', ['name' => '张三']); ?></p>
<p><?php echo __('items_count', ['count' => 5]); ?></p>
<!-- 语言切换链接 -->
<a href="?lang=zh_cn">中文</a>
<a href="?lang=en">English</a>
<a href="?lang=ja">日本語</a>
</body>
</html>
JSON文件实现
如果更喜欢JSON格式:
lang/en.json
{
"welcome": "Welcome",
"login": "Login",
"hello": "Hello, :name"
}
修改Language类
public function setLanguage($lang) {
$lang = $this->sanitizeLanguage($lang);
$this->currentLang = $lang;
$file = __DIR__ . '/../lang/' . $lang . '.json';
if (file_exists($file)) {
$json = file_get_contents($file);
$this->translations = json_decode($json, true);
} else {
$this->translations = [];
}
}
数据库存储(适合大型项目)
数据库表结构
CREATE TABLE translations (
id INT PRIMARY KEY AUTO_INCREMENT,
lang_code VARCHAR(10) NOT NULL,
translation_key VARCHAR(100) NOT NULL,
translation_value TEXT,
UNIQUE KEY unique_trans (lang_code, translation_key)
);
INSERT INTO translations (lang_code, translation_key, translation_value) VALUES
('zh_cn', 'welcome', '欢迎光临'),
('en', 'welcome', 'Welcome');
数据库加载类
class DatabaseLanguage {
private $translations = [];
private $db;
public function __construct($db, $lang) {
$this->db = $db;
$this->loadFromDatabase($lang);
}
private function loadFromDatabase($lang) {
$stmt = $this->db->prepare(
"SELECT translation_key, translation_value
FROM translations
WHERE lang_code = ?"
);
$stmt->execute([$lang]);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$this->translations[$row['translation_key']] = $row['translation_value'];
}
}
}
框架集成(以ThinkPHP为例)
ThinkPHP自带多语言支持:
config/app.php
'lang_switch_on' => true, 'default_lang' => 'zh-cn', 'list' => ['zh-cn', 'en', 'ja'],
语言文件
- application/lang/zh-cn.php
- application/lang/en.php
使用
// 切换语言
session('lang', 'en');
cookie('lang', 'en');
// 获取翻译
lang('welcome');
lang('hello', ['name' => '张三']);
优化建议
-
缓存加载:生产环境可以缓存语言文件
// 使用文件缓存 $cacheFile = __DIR__ . '/../cache/lang_' . $lang . '.php'; if (file_exists($cacheFile)) { $this->translations = include $cacheFile; } else { // 加载并缓存 $this->translations = include $originalFile; file_put_contents($cacheFile, '<?php return ' . var_export($this->translations, true) . ';'); } -
懒加载:只加载需要的模块
public function get($key, $module = 'common') { if (!isset($this->translations[$module])) { $this->loadModule($module); } return $this->translations[$module][$key] ?? $key; } -
使用常量:提高性能
define('LANG_WELCOME', __('welcome'));
- 小项目:使用PHP数组文件,简单快速
- 中等项目:JSON文件,便于非技术人员编辑
- 大型项目:数据库存储,方便管理,支持在线翻译
- 框架项目:使用框架自带的多语言功能
选择哪种方式取决于项目规模和具体需求,核心思想都是一致的:将文本与代码分离,通过键值对实现动态切换。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播