The most often used solution is a strings file. E.g. like following:
# library
class Foo {
public function __construct($lang = 'en') {
$this->strings = require('path/to/langfile.' . $lang . '.php');
$this->message = $this->strings['callMeToo'];
}
public function callMeToo($user) {
return sprintf($this->strings['callMeToo'], $user);
}
}
# strings file
return Array(
'callMeToo' => 'Hi %s, nice to meet you!'
);
You can, to avoid the $this->message
assignment, also work with magic getters:
# library again
class Foo {
# … code from above
function __get($name) {
if(!empty($this->strings[$name])) {
return $this->strings[$name];
}
return null;
}
}
You can even add a loadStrings
method which takes an array of strings from the user and merge it with your internal strings table.
Edit 1: To achieve more flexibility I would change the above approach a little bit. I would add a translation function as object attribute and always call this when I want to localize a string. The default function just looks up the string in the strings table and returns the value itself if it can't find a localized string, just like gettext. The developer using your library could then change the function to his own provided to do a completely different approach of localization.
Date localization is not a problem. Setting the locale is a matter of the software your library is used in. The format itself is a localized string, e.g. $this->translate('%Y-%m-%d')
would return a localized version of the date format string.
Number localization is done by setting the right locale and using functions like sprintf()
.
Currency localization is a problem, though. I think the best approach would be to add a currency translation function (and, maybe for better flexibility, another number formatting function, too) which a developer could overwrite if he wants to change the currency format. Alternatively you could implement format strings for currencies, too. For example %CUR %.02f
– in this example you would replace %CUR
with the currency symbol. Currency symbols itself are localized strings, too.
Edit 2: If you don't want to use setlocale
you have to do a lot of work… basically you have to rewrite strftime()
and sprintf()
to achieve localized dates and numbers. Of course possible, but a lot of work.