1

I have this language system:

$lang = include('lang/en.php'); // default language
$lg = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); // detect language
if ($lg == "de") $lang = array_merge($lang, include('lang/de.php')); // load german file and merge
function __($name,$values) 
{
    global $lang;
    return $lang[$name];
}

lang/en.php looks like this for example:

<?php 
return array(  
    'GREET' => 'Hello '.$values[0].', welcome '.$values[1].'!',
?>

Now I'm trying to output this using variables like this in an array:

$values = array("Max","Home");
echo __('GREET',$values);

This will only output Hello , welcome ! instead of Hello Max, welcome home!

How could I manage to also output the variables?

AlexioVay
  • 4,338
  • 2
  • 31
  • 49

2 Answers2

1

The assignments in the arrays of your language files are evaluated at the time they are included in your script. For example, when you write

<?php 
return array(  
    'GREET' => 'Hello '.$values[0].', welcome '.$values[1].'!',
?>

if at the time PHP interpreter sees this you don't have $values[0] and $values[1] defined, this is going to evaluate without those values. Even if you had those values defined, you wouldn't be able to evaluate them again with different values. This is probably not what you want.

I think you are imagining something like this instead:

<?php 
return array(  
    'GREET' => function(array $values) { return 'Hello '.$values[0].', welcome '.$values[1].'!'; },
?>

And then in your script you'd call it as

$lang[$name]($values);

Pay close attention that by assigning a function to 'GREET' element (instead of a string value), we delay the evaluation until it is actually called. And also that when we now retrieve the $lang[$name] - it is now an anonymous function - and then we can pass it the $values array, which now returns the freshly evaluated string.

However, on a side note, I'd also like to point out that typically the translations are not done like this. Instead they are done by some simple string substitution schemes such as:

$trans['en']['greet'] = 'Hello %%1%%, welcome %%2%%!';

Then in your application you have a translation module or class that takes the name and values and does the string substitution.

Unix One
  • 1,151
  • 7
  • 14
  • Hmm, so if you say typically it's done a different way, should I consider to implement this other way? I choosed this language system, because I read about it some years ago to do it that way I'm doing it now (it was good back then I guess). Is the "typical way" the better way? Can I read something about it somewhere with this substituion scheme? – AlexioVay Apr 20 '16 at 14:50
  • Anyway, your solution works, thank you! But if you really think I shouldn't do it this way, please reply. – AlexioVay Apr 20 '16 at 15:23
  • One advantage of having simple strings for translations is that one doesn't need to write functions to translate. For example, if you wanted to have tools for or enable non-programmers to contribute translations it'd be easier to do with simple strings. However, I'm not suggesting you do it one way or the other, just pointing out typical practice I've observed in the past. On the other hand, there's some elegance in doing this with anonymous functions. – Unix One Apr 20 '16 at 18:33
0

You don't send the values to the lang file, so it doens't know what to do with them. You will get a warning, or maybe even an exception.

$lang = include('lang/en.php'); // default language
$lg = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); // detect language
if ($lg == "de") $lang = array_merge($lang, include('lang/de.php')); // load german file and merge
function __($name,$values) 
{
    global $lang;
    return $lang[$name, $values];
}
Chilion
  • 4,380
  • 4
  • 33
  • 48