PHP中的国际化(i18n):完整指南与示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

PHP中的国际化(i18n):如何打造多语言网站



国际化(i18n)是一种软件设计过程,旨在使软件能够轻松适应不同的语言和地区,而无需修改代码。在PHP中,有几种强大的工具可以实现这一点,它们允许将代码与文本分离,然后动态加载所需的语言。



在本文中,我们将探讨在PHP中实现i18n的主要方法和库,包括内置函数gettext、intl扩展以及诸如Symfony Translation之类的流行库。



1. i18n的基本概念



在深入工具之前,理解关键术语很重要:



  • 区域设置(locale) — 语言和地区的组合(例如,ru_RU、en_US、de_DE)。
  • 翻译 — 将原始字符串替换为另一种语言的等效字符串。
  • 复数形式 — 根据数量正确变化单词(例如,“1个文件”、“2个文件”、“10个文件”)。
  • 格式化 — 根据区域设置调整日期、数字、货币。


2. 内置gettext库



gettext是PHP内置的经典i18n工具。它使用.po(Portable Object)和.mo(Machine Object)文件来存储翻译。



安装与配置



确保在php.ini中启用了gettext扩展:



extension=gettext


基本配置示例:



<?php// 设置区域setlocale(LC_ALL, 'ru_RU.UTF-8');// 指定域(.mo文件名)bindtextdomain('messages', './locale');// 编码bind_textdomain_codeset('messages', 'UTF-8');// 选择域textdomain('messages');

// 使用翻译echo gettext("Hello, World!"); // 输出“Здравствуй, Мир!”// 或简写形式echo _("Hello, World!");?>


文件结构



您的翻译文件应位于locale文件夹中:



locale/├── ru_RU/│   └── LC_MESSAGES/│       └── messages.po│       └── messages.mo└── en_US/    └── LC_MESSAGES/        └── messages.po        └── messages.mo


messages.po文件示例:



msgid "Hello, World!"msgstr "Здравствуй, Мир!"

msgid "Files: %d"msgstr "Файлы: %d"


要编译.po为.mo,请使用msgfmt工具:



msgfmt messages.po -o messages.mo


3. intl扩展(国际化函数)



intl扩展提供了更现代的区域设置处理功能,包括数字、日期和消息的格式化。



安装



sudo apt-get install php-intl  # 适用于Ubuntu/Debian


使用MessageFormatter格式化消息



<?php$locale = 'ru_RU';$message = '{0} приветствует {1}!';$fmt = new MessageFormatter($locale, $message);echo $fmt->format(['PHP', 'Мир']);// 输出:PHP приветствует Мир!?>


复数形式



<?php$locale = 'ru_RU';$pattern = '{0, plural, one {# файл} few {# файла} other {# файлов}}';$fmt = new MessageFormatter($locale, $pattern);echo $fmt->format([1]); // 1 файлecho $fmt->format([2]); // 2 файлаecho $fmt->format([10]); // 10 файлов?>


日期和数字格式化



<?php$locale = 'ru_RU';$fmt = new NumberFormatter($locale, NumberFormatter::DECIMAL);echo $fmt->format(1234567.89); // 1 234 567,89

$dateFmt = new IntlDateFormatter($locale, IntlDateFormatter::LONG, IntlDateFormatter::NONE);echo $dateFmt->f

推荐