php本地打开程序_“正确的方式”对PHP应用程序进行本地化,第2部分

php本地打开程序

Welcome back to this series of articles which teach you how to localize your PHP applications using gettext and its PHP extension. In Part 1 you took your first steps towards towards this by installing gettext and Poedit, creating a translation file, and writing a Hello World script. In this part you’ll lean about each of the function used in the script, and dive more into the gettext library and its usage.

欢迎回到本系列文章,它们教您如何使用gettext及其PHP扩展来本地化PHP应用程序。 在第1部分中,您通过安装gettext和Poedit,创建翻译文件并编写Hello World脚本迈出了第一步。 在这一部分中,您将了解脚本中使用的每个函数,并深入研究gettext库及其用法。

“ Hello World”脚本 (The “Hello World” Script)

To review, Part 1 showed you the following script as TestI18N/test-locale.php:

为了进行回顾,第1部分向您展示了以下脚本TestI18N/test-locale.php

<?php
// I18N support information here
$language = "en_US";
putenv("LANG=" . $language); 
setlocale(LC_ALL, $language);

// Set the text domain as "messages" to 
// use Locale/en_US/LC_MESSAGES/messages.mo
$domain = "messages";
bindtextdomain($domain, "Locale"); 
bind_textdomain_codeset($domain, "UTF-8");

// Use the messages domain
textdomain($domain);

echo _("HELLO_WORLD");

Calling putenv() and setting the LANG environment variable instructs gettext which locale it will be using for this session. en_US is the identifier for English as used in the United States. The first part of the locale is a two-letter lowercase abbreviation for the language according to the ISO 639-1 specification, and the second part is a two-letter uppercase country code according to the ISO 3166-1 alpha-2 specification. setlocale() specifies the locale used in the application and affects how PHP sorts strings, understands date and time formatting, and formats numeric values.

调用putenv()并设置LANG环境变量将指示gettext该会话将使用哪个语言环境。 en_US是在美国使用的英语标识符。 语言环境的第一部分是根据ISO 639-1规范的语言的两个字母的小写缩写,第二部分是根据ISO 3166-1 alpha-2规范的两个字母的大写国家/地区代码。 setlocale()指定应用程序中使用的语言环境,并影响PHP如何对字符串排序,理解日期和时间格式以及格式化数字值。

gettext calls the catalog file used to store the translation messages (the MO file) a domain. The bindtextdomain() function tells gettext where to find the domain to use; the first parameter is the catalog name without the .mo extension, and the second parameter is the path to the parent directory in which the en_US/LC_MESSAGES subpath resides (which in turn is where the translation file resides). If you’re wondering where the subpath en_US/LC_MESSAGES comes from, it is constructed by gettext using the values of the LANG variable you specified using putenv() and the locale category LC_MESSAGES. You can call bindtextdomain() several times to bind as many domains as you want, in the event you’ve split your translations up throughout multiple files.

gettext调用用于将翻译消息(MO文件)存储在域中的目录文件。 bindtextdomain()函数告诉gettext在哪里可以找到要使用的域。 第一个参数是不带.mo扩展名的目录名称,第二个参数是en_US/LC_MESSAGES子路径所驻留的父目录的路径(而该路径又是转换文件所驻留的位置)。 如果您想知道子路径en_US/LC_MESSAGES来源,它由gettext使用您使用putenv()和语言环境类别LC_MESSAGES指定的LANG变量的值构造而成。 如果将翻译拆分为多个文件,则可以多次调用bindtextdomain()来绑定bindtextdomain()多个域。

Calling bind_textdomain_codeset() is very important because not doing so can lead to unexpected characters in your output when using non-ASCII letters. Since the catalog messages are encoded in UTF-8, that is what the example code sets as the codeset. I always recommend using UTF-8 as is the most widely supported Unicode encoding. Don’t use other less-known encodings unless you know exactly what you are doing; you will encounter serious problems, especially on the web.

调用bind_textdomain_codeset()非常重要,因为如果不这样做,使用非ASCII字母会导致输出中出现意外字符。 由于目录消息是使用UTF-8编码的,因此示例代码将其设置为代码集。 我总是建议使用UTF-8,因为它是最广泛支持的Unicode编码。 除非您确切地知道自己在做什么,否则不要使用其他鲜为人知的编码。 您将遇到严重的问题,尤其是在网络上。

The call textdomain() tells gettext which domain to use for any subsequent calls to gettext(), or its shorthand alias _(), or its plural form lookup method ngettext(). I’ll talk about dealing with plural forms in the next installment, but for now you should know that all three of these methods lookup messages in the current domain specified with textdomain().

调用textdomain()告诉gettext哪个域用于随后的对gettext()或其速记别名_()或其复数形式查找方法ngettext()任何后续调用。 我将在下一部分中讨论处理复数形式,但是现在您应该知道所有这三种方法都在使用textdomain()指定的当前域中查找消息。

Lastly, the script calls _(), which looks up the msgid HELLO_WORLD in the messages.mo file and returns the msgstr associated with it, the text Hello World!

最后,脚本调用_() ,该脚本在messages.mo文件中查找msgid HELLO_WORLD并返回与其关联的msgstr,即文本Hello World!。

缺少翻译字符串 (Missing Translation Strings)

Now that you have a basic understanding of how this simple script looks up replacements for translations, try changing the domain.

现在,您已经对这个简单的脚本如何查找翻译的替代品有了基本的了解,请尝试更改域。

<?php
$language = "en_US";
putenv("LANG=" . $language); 
setlocale(LC_ALL, $language);

$domain = "foo";
bindtextdomain($domain, "Locale"); 
bind_textdomain_codeset($domain, "UTF-8");
// ...

gettext will try to look up the catalog Locale/en_US/LC_MESSAGES/foo.mo, which shouldn’t exist.

gettext将尝试查找目录Locale/en_US/LC_MESSAGES/foo.mo ,该目录不应该存在。

When you view the script’s output you’ll see HELLO_WORLD instead of the Hello World! gettext can’t perform a translation because there isn’t a valid catalog, though another scenario might be the given msgid might not exist in any catalogs registered with gettext, and it is smart enough to use the original string you supplied.

当您查看脚本的输出时,将看到HELLO_WORLD而不是Hello World! gettext无法执行转换,因为没有有效的目录,尽管在给gettext注册的任何目录中,可能也没有给定的msgid,这是另一种情况,它足够聪明来使用您提供的原始字符串。

定位多个语言环境 (Targeting Multiple Locales)

In a real-world application, you will typically use your target language’s strings as the IDs throughout your code. This makes the code a bit clearer and the fallback of a translation failure more user friendly. For example, if your application uses English and French as the target languages, you can use English as the ID strings and then create French catalogs to replace the English.

在实际应用程序中,通常会在整个代码中使用目标语言的字符串作为ID。 这使代码更加清晰,翻译失败的后退更加用户友好。 例如,如果您的应用程序使用英语和法语作为目标语言,则可以使用英语作为ID字符串,然后创建法语目录来替换英语。

In the same TestI18N/Locale directory, create a new directory named fr_FR containing another LC_MESSAGES directory, and use the procedures outlined in Part 1 to create a new catalog for French. When you’re finished, you should have the following hierarchy:

在同一TestI18N/Locale目录中,创建一个名为fr_FR的新目录, fr_FR包含另一个LC_MESSAGES目录,并使用第1部分中概述的过程为法语创建一个新目录。 完成后,您应该具有以下层次结构:

en_US and fr_FR directories

When you specify the catalog settings in Poedit, remember to set French as the language and France as the country.

在Poedit中指定目录设置时,请记住将法语设置为语言,将法国设置为国家。

Poedit settings window for French

My French messages.po will look like this when opened in a text editor:

在文本编辑器中打开时,我的法语messages.po看起来像这样:


msgid ""
msgstr ""
"Project-Id-Version: TestProjectn"
"POT-Creation-Date: n"
"PO-Revision-Date: n"
"Last-Translator: FIRSTNAME LASTNAME <email@example.com>n"
"Language-Team: MyTeam <team@example.com>n"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=utf-8n"
"Content-Transfer-Encoding: 8bitn"
"X-Poedit-Language: Frenchn"
"X-Poedit-Country: FRANCEn"
"X-Poedit-SourceCharset: utf-8n"

#Test token 1
msgid "HELLO_WORLD"
msgstr "Bonjour tout le monde!"

#Test token 2
msgid "TEST_TRANSLATION"
msgstr "Test de traduction..."

Most of the header lines of the file are self explanatory, so I’ll skip right to the actual translation lines which start with the first msgid after the headers. Notice that there are two strings for each phrase to be translate, the msgid which is the ID string in your code gettext will look up, and the msgstr which is the translated message which gettext will substitute for the ID. The first definition instructs gettext to use Bonjour tout le monde! whenever it sees HELLO_WORLD. The second instructs gettext to use Test de traduction… for TEST_TRANSLATION.

该文件的大多数标题行都是不言自明的,因此我将直接跳到实际的翻译行,该行以标题之后的第一个msgid开头。 请注意,每个要翻译的短语都有两个字符串,将查找代码gettext中的ID字符串msgid,以及将gettext替换为ID的已翻译消息msgstr。 第一个定义指示gettext使用Bonjour tomont le monde! 每当看到HELLO_WORLD 。 第二条指令gettext将Test TEST_TRANSLATION 用于TEST_TRANSLATION

Open the catalog file again in Poedit and click the Save Catalog entry in the icon bar to save and compile it. Then modify the PHP script to use fr_FR instead of en_US. When you run it, you’ll see the output in your browser is now French!

在Poedit中再次打开目录文件,然后单击图标栏中的“保存目录”条目以保存并编译它。 然后,修改PHP脚本以使用fr_FR而不是en_US 。 运行它时,您会看到浏览器中的输出现在是法语!

摘要 (Summary)

In this part you learned what each function call does in the Hello World script introduced in Part 1. In terms of its API, gettext isn’t really a large library. There are only a handful of functions, most of which you will only use once in your entire application. The most frequently used will be gettext(), or it’s shorthand alias _(), and its plural form equivalent ngettext(). You also learned how to target multiple Locales (en_US and fr_FR in our example), and how gettext falls back to the msgid when its missing a translation.

在这一部分中,您了解了第1部分介绍的Hello World脚本中每个函数调用的作用。就其API而言,gettext并不是真正的大库。 只有少数功能,您在整个应用程序中只会使用其中的大多数功能。 最常用的将是gettext() ,或者它的简写别名_() ,以及其复数形式的等效ngettext() 。 您还学习了如何定位多个语言环境(在我们的示例中为en_USfr_FR ),以及gettext在缺少翻译时如何退回到msgid。

In the next part you’ll see how to start doing real world localization by organizing the directories, switching between languages, choosing a fallback language, and overriding the current selected messages domain.

在下一部分中,您将看到如何通过组织目录,在语言之间切换,选择备用语言以及覆盖当前选定的消息域来开始进行真实世界的本地化。

Image via sgame / Shutterstock

图片来自sgame / Shutterstock

翻译自: https://www.sitepoint.com/localizing-php-applications-2/

php本地打开程序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值