Localizing Output in PHP

An application used by people all over the world not only has to handle different character sets properly, but also has to produce messages in different languages. One person’s “Click here” is another’s “Cliquez ici” or The MessageFormatter

class helps you generate messages that are appropriately localized for different places.

First, you need to build a message catalog. This is a list of translated messages for each of the locales you support. They could be simple strings such as Click here, or they may contain markers for values to be interpolated, such as My favorite food is {0}, in which {0} should be replaced with a word.

In a big application, you may have hundreds of different items in your message cata­log for each locale. To explain how MessageFormatter works, Example 20-5 shows a few entries in a sample catalog.

Example 20-5. Defining a message catalog

$messages = array();

$messages[‘en_US’] = array(‘FAVORITE_FOODS’ => ‘My favorite food is {0}’,

‘COOKIE’ => ‘cookie’,

‘SQUASH’ => ‘squash’);

$messages[‘en_GB’] = array(‘FAVORITE_FOODS’ => ‘My favourite food is {0}’,

‘COOKIE’ => ‘biscuit’,

‘SQUASH’ => ‘marrow’);

The keys in the $messages array are locale strings. The values are the messages appropriately translated for each locale, indexed by a key that is used to refer to the message later.

To create a locale-specific message, create a new MessageFormatter object by provid­ing a locale and a message format to its constructor, as shown in Example 20-6.

Example 20-6. Formatting a message

$fmtfavs = new MessageFormatter(‘en_GB’, $messages[‘en_GB’][‘FAVORITE_FOODS’]);

$fmtcookie = new MessageFormatter(‘en_GB’, $messages[‘en_GB’][‘COOKIE’]);

// This returns “biscuit”

$cookie = $fmtcookie->format(array());

// This prints the sentence with “biscuit” substituted

print $fmtfavs->format(array($cookie));

Example 20-6 prints:

My favourite food is biscuit

When a message format has curly braces, the elements in the array passed as an argu­ment to fomat() are substituted for the curly braces.

In Example 20-6, we had to do most of the work to figure out the right en_GB strings to use, so MessageFormatter didn’t add much. It really helps, though, when you need locale-specific formatting of numbers and other data. Example 20-7 shows how MessageFormatter can properly handle numbers and money amounts in different locales.

Example 20-7. Formatting numbers in a message

$msg = “The cost is {0,number,currency}.”;

$fmtUS = new MessageFormatter(‘en_US’, $msg);

$fmtGB = new MessageFormatter(‘en_GB’, $msg);

print $fmtUS->format(array(4.21)) . “\n”;

print $fmtGB->format(array(4.21)) . “\n”;

Example 20-7 prints:

The cost is $4.21.

The cost is £4.21.

Because MessageFormatter relies on the powerful ICU library, it uses its internal database of currency symbols, number formatting, and other rules about how differ­ent places and languages organize information to produce proper output.

The MessageFormatter class can do lots more than what’s described here, such as for­mat text properly for singular and plural, handle languages where the gender of a word affects how it’s written, and format dates and times. If you want to learn more, check out the ICU User Guide to Formatting and Parsing.

Source: Sklar David (2016), Learning PHP: A Gentle Introduction to the Web’s Most Popular Language, O’Reilly Media; 1st edition.

Leave a Reply

Your email address will not be published. Required fields are marked *