PHP 国际化库

Github Repo

一个简单高效的 PHP 国际化(i18n)库,允许你在应用程序中管理多种语言。

该项目受到 Philipp Schröeri18n 库 的启发。原始库在运行时不能动态切换语言,这是一个限制。这个分支旨在解决这个问题并提供一个更灵活的解决方案。

如果你不需要动态语言切换功能,你仍然可以使用 Philipp Schröer 的原始 i18n 库

特性

  • 支持语言变体如 “en-US”、“zh-CN” 等。
  • 自动检测用户的语言偏好。
  • 支持后备语言,以确保所有字符串都有默认翻译。
  • 缓存机制以提高性能。
  • 在运行时动态更改语言。

安装

你可以通过 Composer 安装库:

composer require tangramor/php-i18n

或者你可以下载 i18n.php 文件并将其包含在你的项目中。

如何使用这个库

配置

语言文件应该放在指定的 filePath 目录中,并遵循命名约定 {LANGUAGE}.ini。例如,美国英语为 en-US.ini

这个分支禁用了 YAML 格式,仅支持 INI 格式。因为要支持 YAML,我们需要添加依赖 “mustangostang/spyc” 用于 YAML,这对这个项目来说是不必要的。

语言文件示例 (en-US.ini)
greeting = "Hello, World!"

[category]
somethingother = "Something other..."
设置
  • 语言文件路径(默认:./lang/{LANGUAGE}.ini
  • 缓存文件路径(默认:./langcache/
  • 保留语言区域变体:如果设置为 true,语言代码字符串中的区域变体如 en-US 和 en-GB 将被保留,否则将被截断为 en(默认:true,注意在原始 i18n 库中这个值默认为 false
  • 后备语言,如果没有用户语言可用(默认:en-US,注意在原始 i18n 库中这个值默认为 en
  • 强制语言,如果你想强制使用一种语言(默认:无)
  • 节分隔符:这用于分隔语言类中的节。如果你将分隔符设置为 _abc_ ,如果你在你的 ini 中使用了类别,你可以使用 $L->t('category_abc_stringname') 访问你的本地化字符串。(默认:_
  • 将后备语言的键合并到当前语言中。(默认:false

使用方法

初始化:创建 i18n 类的实例并用你希望的设置初始化它。
$i18n = new i18n();
$i18n->init();  //使用默认设置
设置语言偏好:可选地,你可以设置强制语言或后备语言。
$i18n->setForcedLang('zh-CN');
// 或
$i18n->setFallbackLang('en-US');

$i18n->init();
其他设置:你也可以设置其他设置,如文件路径、缓存路径等。
$i18n->setCachePath('/tmp/langcache');  //缓存文件路径(默认:./langcache/)
$i18n->setFilePath('/app/lang/{LANGUAGE}.ini'); // 语言文件路径(默认:./lang/{LANGUAGE}.ini)
$i18n->setMergeFallback(false); // 使后备语言的键可用(默认:false)
$i18n->setLangVariantEnabled(false);    //允许区域变体如 "en-us", "en-gb" 等。如果设置为 false,将提供 "en"。(默认:true)
$i18n->setSectionSeparator('');    //这用于分隔语言类中的节(默认:)

$i18n->init();
翻译:使用 LangManager 类的 translate 方法获取翻译后的字符串。
$L = LangManager::getInstance($i18n->getAppliedLang());

echo $L->translate('greeting');
// 或使用简写形式
echo $L->t('greeting');
// 输出:Hello, World!

echo $L->t('category_somethingother');
// 输出:Something other...

你可以在运行时通过调用 LangManager::getInstance($otherLang) 动态更改翻译语言。

查看测试代码中的示例:

$L1 = LangManager::getInstance('en-US');
$this->assertEquals("Hello, World!", $L1->t('greeting'));

$L2 = LangManager::getInstance('zh-CN');
$this->assertEquals("世界,你好!", $L2->t('greeting'));

缓存

该库使用缓存机制存储编译后的语言文件。确保缓存路径目录可写。

用户语言检测的工作原理

此类尝试通过以下顺序检测用户的语言:

  • 强制语言(如果设置)
  • HTTP 头 ‘CURRENT_LANGUAGE’
  • GET 参数 ‘lang’($_GET['lang']
  • SESSION 参数 ‘lang’($_SESSION['lang']
  • HTTP_ACCEPT_LANGUAGE(可以是多种语言)($_SERVER['HTTP_ACCEPT_LANGUAGE']
  • COOKIE 存储的变量 ‘lang’($_COOKIE['lang']
  • 后备语言

php-i18n 将删除所有不是以下字符之一的字符:A-Z, a-z 或 0-9,以防止任意文件包含。之后,该类会搜索语言文件。例如,如果你将 GET 参数 ‘lang’ 设置为 ‘en-US’ 而没有设置强制语言,该类会尝试查找文件 lang/en-US.ini(如果设置 langFilePath 为默认(lang/{LANGUAGE}.ini))。如果这个文件不存在,php-i18n 会尝试查找会话变量中定义的语言文件,依此类推。

在 JavaScript 中设置 ‘CURRENT_LANGUAGE’ 的示例

你可以在你的 axios 请求中设置 ‘CURRENT_LANGUAGE’ 头以将语言传递给服务器。

以下示例拦截 axios 请求以添加 ‘CURRENT_LANGUAGE’ 头,你可以将其更改为你自己的方式。

import axios from 'axios';
import i18n from './i18n';

axios.interceptors.request.use(function (config) {
    config.headers['CURRENT_LANGUAGE'] = i18n.locale;
    return config
}, function (error) {
    return Promise.reject(error);
});

如何更改此实现

你可以通过扩展 i18n 类并覆盖 getUserLangs() 方法来更改用户检测:

<?php
	require_once 'i18n.php';
	class My_i18n extends i18n {

		public function getUserLangs() {
			$userLangs = new array();

			$userLangs[] = $_GET['language'];

			$userLangs[] = $_SESSION['userlanguage'];

			return $userLangs;
		}

	}

	$i18n = new My_i18n();
	// [...]
?>

这个非常基本的扩展仅使用 GET 参数 ‘language’ 和会话参数 ‘userlanguage’。你可以看到这个方法必须返回一个数组。

测试

要运行测试,你需要在测试文件夹下安装 phpunit/phpunit 包。

cd test
composer install

#或

composer require --dev phpunit/phpunit

然后在测试文件夹下运行以下命令进行测试:

./vendor/bin/phpunit --testdox tests

许可证

该项目根据 MIT 许可证授权 - 详情请参阅 LICENSE 文件。

贡献

欢迎贡献!请随时 fork 项目并提交 pull requests。

联系方式

如有任何问题或问题,请打开问题或直接联系作者。

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值