As discussed in the previous articles on PHP internationalization, PHP provides native support for string translation using gettext and PHP arrays. These can be used in any PHP project. Additionally, some popular PHP frameworks offer their own way of string translation.
In this article, I want to provide a brief summary of the internationalization process with five of the most popular PHP frameworks currently out there. In this How-To you will read about using CodeIgniter, CakePHP, Zend, Yii and Symfony. If you would like us to focus on any of these (or some other PHP framework of your choice) in a future article of its own, please leave a comment.
Internationalization with 5 popular PHP frameworks
CodeIgniter framework
CodeIgniter Language Class provides functions to retrieve language files and lines of text for purpose of internationalization. The language files are located within the language directory. CodeIgniter automatically looks for the language directory in two locations, first within the "languages" subdirectory of the application, and then, if not found, within the "languages" subdirectory of the CodeIgniter system directory. Each language is stored in its own subdirectory. For example, English language files can be stored either in
system/language/english
or
application/language/english
Language resource file names must end with _lang.php. Within the file, a line of text is assigned to a $lang array in each line this way:
$lang['language_key'] = "The actual message to be shown";
Recommended practice is to prefix all the keys with the name of the file in which they are located, in order to avoid collision with similar keys in different files. For example, the error message that informs the user about the missing email address that is located in the error_lang.php could have this key: "error_missing_email".
Before fetching lines from any file, it has to be loaded first:
$this->lang->load('filename', 'language');
Filename is the name of the file without the extension. So for the previous example with error_lang.php, the filename to supply to the load function would simply be "error". The language specifies the set that contains the file. If the second parameter is missing, the default language set in the application/config/config.php is used instead.
After the language file is loaded, a line of text can be fetched and echoed like this:
echo $this->lang->line('language_key');
Language files that are used globally can be auto-loaded by CodeIgniter. Auto loading can be set up in the autoload array in application/config/autoload.php.
Further reading:
CakePHP framework
CakePHP uses its own implementation of Gettext. In the previous blog article I described how gettext (po) files can be created. Functions used in CakePHP for application internationalization are as follows:
- __(string $string_id[, $formatArgs]) - returns the string from the current domain of the loaded language for the supplied ID. Strings used for translations are treated as format strings for sprintf(), and additional arguments can be supplied to replace any placeholders in the string.
- __d(string $domain, string $msg, mixed $args = null) - it allows overriding the current domain for a single message lookup
- __n(string $singular, string $plural, integer $count, mixed $args = null) - returns the correct plural form of a message identified by $singular and $plural for count $count
- __dn(string $domain, string $singular, string $plural, integer $count, mixed $args = null) - overrides the current domain for a single plural message lookup. Returns correct plural form of message identified by $singular and $plural for count $count from domain $domain
A complete list of global functions including those used for localization can be found in the CakePHP documentation.
Further reading:
- Previous blog article on PHP internationalization using gettext
- Internationalization & Localization with CakePHP
ZEND framework
The Zend framework offers its own complete solution for localization and internationalization. It includes support for both gettext as well as some other resource file formats.
Available adapters for Zend_translate (a library used within the framework to handle translation) are:
- Array (use PHP arrays)
- Csv (use comma separated (*.csv/*.txt) files)
- Gettext (use binary gettext (*.mo) files)
- Ini (use simple INI (*.ini) files)
- Tbx (use termbase exchange (*.tbx/*.xml) files)
- Tmx (use tmx (*.tmx/*.xml) files)
- Qt (use qt linguist (*.ts) files)
- Xliff (use xliff (*.xliff/*.xml) files)
- XmlTm (use xmltm (*.xml) files)
Further reading:
Symfony framework
In Symfony, translation of text is done through the translator service. To translate a message, the trans() method is used, following this process:
- the locale is determined (from the request or a session variable)
- a catalog of translated messages is loaded from the translation resource files defined for that locale
- the requested translation is returned
The Symfony framework provides support for these loaders by default:
xliff
: XLIFF filephp
: PHP fileyml
: YAML file
Howerver, custom loaders can be created by implementing the LoadInterface interface.
Further reading:
Yii Framework
With the Yii framework, message translation is done by calling Yii::t() method. When translating a message, its category has to be specified since a message may be translated differently under different categories (contexts). For example, the category yii is reserved for messages used by the Yii framework core code.
Parameter placeholders within the messages are replaced with the actual parameter values when calling Yii::t(). For example, the following message translation request would replace the {alias} placeholder in the original message with the actual alias value.
Yii::t('app', 'Path alias "{alias}" is redefined.', array('{alias}'=>$alias))
Translated messages are stored in a repositories called message sources. A message source is represented as an instance of CMessageSource or its child class. When Yii::t() is invoked, it will look for the message in the message source and returns its translated version if it is found.
Yii comes with the following types of message sources:
- CPhpMessageSource: the message translations are stored as key-value pairs in a PHP array. The original message is the key and the translated message is the value. Each array represents the translations for a particular category of messages and is stored in a separate PHP script file whose name is the category name. The PHP translation files for the same language are stored under the same directory named as the locale ID. All these directories are located under the directory specified by basePath.
- CGettextMessageSource: the message translations are stored as GNU Gettext files. For more information on gettext, you can check our previous blog post.
- CDbMessageSource: the message translations are stored in database tables.
Custom message sources can be created as well by extending CMessageSource.
Further reading:
These quite popular PHP frameworks are not the only approaches to internationalization, let me know which ones you use and what your experiences are with them. We've outlined some approaches to getting your applications on the road towards localization before, and we'll focus on some other programming languages and formats in future tutorials, too. Most of these are either based on customer experiences or our lessons learned from developing Lingohub. We're looking forward to your comments.