PHP国际化:如何用同一种语言与世界对话

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

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

开始课程

为什么您的PHP网站应该使用不同语言?

\n\n

想象一下:您创建了一个完美的产品——快速、便捷、能解决问题。但有一个障碍:您的界面只支持俄语。来自德国、日本或巴西的潜在客户因为看不懂按钮而直接关闭了标签页。这不仅仅是利润损失——这是整个市场的损失。

\n\n

国际化(i18n——来自“internationalization”,其中i和n之间有18个字母)和本地化(l10n)不是创业公司的“勾选框”,而是一种战略工具。许多开发人员害怕这个词,认为必须重写所有代码。实际上,在PHP中组织翻译是一个优雅的过程,它使代码更清晰,业务更全球化。

\n\n

在本文中,我们将探讨PHP应用程序国际化的三种实际方法:从简单的数组到强大的intl扩展和经典的gettext。您将学习如何不仅仅是翻译文本,还能正确处理日期、数字和复数形式——因为阿拉伯语、波兰语或俄语有各自的变格规则。

\n\n

PHP中i18n的主要方法

\n\n

在编写代码之前,需要选择架构。所有方法大致可分为三类。选择哪一种取决于项目规模和性能要求。

\n\n

1. 数组和ini文件(DIY方法)

\n\n

最简单的方法——将翻译存储在关联数组或.ini文件中。非常适合小型项目或MVP。

\n\n
// lang/ru.php\nreturn [\n    'welcome' => '欢迎来到网站!',\n    'logout' => '退出',\n    'cart_empty' => '购物车为空'\n];\n\n// lang/en.php\nreturn [\n    'welcome' => 'Welcome to the website!',\n    'logout' => 'Logout',\n    'cart_empty' => 'Cart is empty'\n];
\n\n

使用起来很简单:根据用户的会话或cookie加载相应的文件。

\n\n
function __($key) {\n    static $lang = null;\n    if ($lang === null) {\n        $locale = $_SESSION['lang'] ?? 'ru';\n        $lang = include "lang/{$locale}.php";\n    }\n    return $lang[$key] ?? $key;\n}\n\necho __('welcome'); // 欢迎来到网站!
\n\n

优点:简单,不需要扩展,易于缓存(甚至可以保存在Redis中)。
\n缺点:不支持复数形式(需要自己实现),不适合大型项目(一个文件中有成千上万个键)。

\n\n

2. Gettext——经典之作

\n\n

Gettext是Unix世界中国际化的实际标准。在PHP中,它通过gettext扩展提供。这是一个强大的工具,用于WordPress、Drupal和Symfony。

\n\n

首先创建.po文件(例如,用于俄语):

\n\n
# ru_RU/LC_MESSAGES/messages.po\nmsgid "Hello, %s!"\nmsgstr "您好,%s!"\n\nmsgid "You have %d new message"\nmsgid_plural "You have %d new messages"\nmsgstr[0] "您有 %d 条新消息"\nmsgstr[1] "您有 %d 条新消息"\nmsgstr[2] "您有 %d 条新消息"
\n\n

然后使用msgfmt工具编译成.mo文件。在PHP代码中如下所示:

\n\n
putenv('LC_ALL=ru_RU.UTF-8');\nsetlocale(LC_ALL, 'ru_RU.UTF-8');\nbindtextdomain('messages', './locale');\ntextdomain('messages');\n\necho gettext('Hello, %s!', '阿列克谢'); // 您好,阿列克谢!\n\n// 复数形式——神奇:\necho ngettext('%d message', '%d messages', 3); // 3 条消息
\n\n

顺便说一下,为了加快开发速度,可以使用Poedit——它会高亮显示未翻译的字符串。

\n\n

3. Intl扩展(PHP 5.3+)

\n\n

如果您不仅需要翻译文本,还需要根据国家标准正确格式化数字、日期或货币——请使用Intl。它是ICU(International Components for Unicode)库的扩展。

\n\n
// 数字格式化                

博客

书籍推荐