PHP国际化与多语言支持实现

国际化(i18n)是面向多语言用户的应用必须考虑的问题。PHP提供了gettext扩展用于翻译,也可以自己实现简单的多语言系统。

先看看最基本的数组翻译方式,适合小型项目:

```php
class Translator
{
private array $translations = [];
private string $locale;

public function __construct(string $locale = 'zh_CN')
{
$this->locale = $locale;
$this->loadTranslations();
}

private function loadTranslations(): void
{
$file = __DIR__ . "/lang/{$this->locale}.php";
if (file_exists($file)) {
$this->translations = require $file;
}
}

public function trans(string $key, array $params = []): string
{
$message = $this->translations[$key] ?? $key;

foreach ($params as $name => $value) {
$message = str_replace(":{$name}", (string)$value, $message);
}

return $message;
}

public function setLocale(string $locale): void
{
$this->locale = $locale;
$this->loadTranslations();
}

public function getLocale(): string
{
return $this->locale;
}

public function choice(string $key, int $number, array $params = []): string
{
$messages = $this->translations[$key] ?? [$key];
$index = $number === 1 ? 0 : 1;
$message = $messages[$index] ?? $messages[0];

$params['count'] = $number;
foreach ($params as $name => $value) {
$message = str_replace(":{$name}", (string)$value, $message);
}

return $message;
}
}
?>

// lang/zh_CN.php
return [
'welcome' => '欢迎来到我们的网站',
'greeting' => '你好,:name!',
'logout' => '退出登录',
'login' => '登录',
'register' => '注册',
'notifications' => '通知',
'new_message' => '你有:count条新消息',
'file_uploaded' => '已上传文件:file',
'email_required' => '邮箱不能为空',
'email_invalid' => '邮箱格式不正确',
'login_success' => '登录成功',
'login_failed' => '登录失败',
'order_placed' => '订单:order_id已创建',
'order_shipped' => '订单:order_id已发货',
'items_count' => [':count个项目', ':count个项目'],
];
?>

// lang/en.php
return [
'welcome' => 'Welcome to our website',
'greeting' => 'Hello, :name!',
'logout' => 'Logout',
'login' => 'Login',
'register' => 'Register',
'notifications' => 'Notifications',
'new_message' => 'You have :count new messages',
'file_uploaded' => 'File :file has been uploaded',
'email_required' => 'Email is required',
'email_invalid' => 'Invalid email format',
'login_success' => 'Login successful',
'login_failed' => 'Login failed',
'order_placed' => 'Order :order_id has been created',
'order_shipped' => 'Order :order_id has been shipped',
'items_count' => [':count item', ':count items'],
];
?>

// 使用翻译器
$translator = new Translator('zh_CN');
echo $translator->trans('welcome') . "\n";
echo $translator->trans('greeting', ['name' => '张三']) . "\n";
echo $translator->trans('new_message', ['count' => 5]) . "\n";
echo $translator->choice('items_count', 1, ['count' => 1]) . "\n";
echo $translator->choice('items_count', 5, ['count' => 5]) . "\n";

// 切换语言
$translator->setLocale('en');
echo $translator->trans('welcome') . "\n";
echo $translator->trans('new_message', ['count' => 3]) . "\n";
?>
```

国际化需要注意字符编码。PHP的mbstring扩展提供了多字节字符串处理支持:

```php
// 多字节字符串处理
$chineseText = "你好世界";
echo "长度: " . mb_strlen($chineseText, 'UTF-8') . "\n";
echo "截取: " . mb_substr($chineseText, 0, 2, 'UTF-8') . "\n";

// 设置内部编码
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
ob_start('mb_output_handler');

// 日期时间本地化
$timestamp = time();
$formats = [
'zh_CN' => 'Y年m月d日 H:i:s',
'en_US' => 'm/d/Y h:i:s A',
'ja_JP' => 'Y年m月d日 H時i分s秒',
];

foreach ($formats as $locale => $format) {
setlocale(LC_TIME, $locale . '.UTF-8');
echo "$locale: " . strftime($format, $timestamp) . "\n";
}
?>
```

多语言项目还需要考虑文本方向、数字格式、货币符号、时区等差异。在实际项目中,建议使用成熟的国际化库或框架的多语言支持功能,避免自己从头实现。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐