This article delves into advanced techniques for using the gettext library in PHP, focusing on fallback locales, locale switching, and overriding message domains.
Key Concepts:
msgids
in other domains streamlines translation and improves performance. Avoid translating the default language to itself.dgettext()
to switch between multiple translation domains. Remember that gettext()
uses only one default domain, set via textdomain()
, while dgettext()
requires domains to be pre-bound using bindtextdomain()
.Directory Structure and Fallback Locales:
An optimal directory structure avoids unnecessary translation of the default locale (e.g., en_US). Instead of using identifiers like "HELLO_WORLD", use the actual default language string directly as the msgid
. This approach minimizes processing overhead.
The image below illustrates a sample directory structure:
Example translation files (.po
and compiled .mo
):
French (fr_FR
):
<code>#Test token 1 msgid "Hello World!" msgstr "Bonjour tout le monde!" #Test token 2 msgid "Testing Translation..." msgstr "Test de traduction..."</code>
Spanish (es_ES
):
<code>#Test token 1 msgid "Hello World!" msgstr "¡Hola mundo!" #Test token 2 msgid "Testing Translation..." msgstr "Prueba de traducción..."</code>
Arabic (ar_EG
):
<code>#Test token 1 msgid "Hello World!" msgstr "!أهلا بالعالم" #Test token 2 msgid "Testing Translation..." msgstr "...اختبار الترجمة"</code>
Switching Locales:
The locale.php
file manages locale selection using GET parameters or sessions:
<?php session_start(); $language = isset($_GET["lang"]) ? $_GET["lang"] : (isset($_SESSION["lang"]) ? $_SESSION["lang"] : "en_US"); $_SESSION["Language"] = $language; $folder = "Locale"; $domain = "messages"; $encoding = "UTF-8"; putenv("LANG=" . $language); setlocale(LC_ALL, $language); bindtextdomain($domain, $folder); bind_textdomain_codeset($domain, $encoding); textdomain($domain); ?>
A sample usage in test-locale.php
:
<?php require_once "locale.php"; echo _("Hello World!"), "<br></br>"; echo _("Testing Translation..."); ?>
Accessing test-locale.php?lang=fr_FR
will output the French translation.
Overriding the Current Domain:
Use dgettext()
to access translations from a different domain (e.g., "errors"). Crucially, remember to bind this domain using bindtextdomain()
in locale.php
:
<?php // ... (locale.php code) ... bindtextdomain("errors", "Locale"); bind_textdomain_codeset("errors", "UTF-8"); // ... (rest of locale.php code) ... ?>
In test-locale.php
:
<?php // ... (include locale.php) ... echo "<br></br>"; echo dgettext("errors", "Error getting content"), "<br></br>"; echo dgettext("errors", "Error saving data"); ?>
This will correctly translate "Error getting content" and "Error saving data" if translations exist in the "errors" domain for the selected locale.
Summary and FAQ:
This section summarizes the key learnings and provides answers to frequently asked questions about PHP localization, covering topics such as best practices, handling plurals, right-to-left languages, and managing translations. The FAQ section is extensive and provides in-depth information on various aspects of PHP localization. The original FAQ section has been retained in its entirety.
The above is the detailed content of phpmaster | Localizing PHP Applications Part 3: Nov 2011 - Sitepoint. For more information, please follow other related articles on the PHP Chinese website!