I am working on multilingual application with a centralized language system. It's based on language files for each language and a simple helper function:
en.php
$lang['access_denied'] = "Access denied.";
$lang['action-required'] = "You need to choose an action.";
...
return $lang;
language_helper.php
...
function __($line) {
return $lang[$line];
}
Up til now, all strings were system messages addressed to the current user, hence I always could do it that way. Now, I need create other messages, where the string should depend on a dynamic value. E.g. in a template file I want to echo the number of action points. If the user only has 1 point, it should echo "You have 1 point."; but for zero or more than 1 point it should be "You have 12 points."
For substitution purposes (both strings and numbers) I created a new function
function __s($line, $subs = array()) {
$text = $lang[$line];
while (count($subs) > 0) {
$text = preg_replace('/%s/', array_shift($subs), $text, 1);
}
return $text;
}
Call to function looks like __s('current_points', array($points))
.
$lang['current_points']
in this case would be "You have %s point(s)."
, which works well.
Taking it a step further, I want to get rid of the "(s)" part. So I created yet another function
function __c($line, $subs = array()) {
$text = $lang[$line];
$text = (isset($sub[0] && $sub[0] == 1) ? $text[0] : $text[1];
while (count($subs) > 0) {
$text = preg_replace('/%d/', array_shift($subs), $text, 1);
}
return $text;
}
Call to function looks still like __s('current_points', array($points))
.
$lang['current_points']
is now array("You have %d point.","You have %d points.")
.
How would I now combine these two functions. E.g. if I want to print the username along with the points (like in a ranking). The function call would be something like __x('current_points', array($username,$points))
with $lang['current_points']
being array("$s has %d point.","%s has %d points.")
.
I tried to employ preg_replace_callback()
but I am having trouble passing the substitute values to that callback function.
$text = preg_replace_callback('/%([sd])/',
create_function(
'$type',
'switch($type) {
case "s": return array_shift($subs); break;
case "d": return array_shift($subs); break;
}'),
$text);
Apparently, $subs is not defined as I am getting "out of memory" errors as if the function is not leaving the while loop.
Could anyone point me in the right direction? There's probably a complete different (and better) way to approach this problem. Also, I still want to expand it like this:
$lang['invite_party'] = "%u invited you to $g party.";
should become Adam invited you to his party."
for males and "Betty invited you to her party."
for females. The passed $subs
value for both $u
and $g
would be an user object.