Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am developing a multilingual site, so i needed some sort of a function to detect user locale, as well as not to scare away search engines, so I wrote this kind of a method to detect locale. The priority is as following:

  1. We look if user has active language in $_SESSION;

  2. If not, we look in the database to detect user preference;

  3. If nothing in the database, we look on the domain name and try to detect locale from domain name and superglobal $_SERVER;

  4. If we failed, we look at user's browser locale ($_SERVER again) and try to detect from it.

  5. If we are totally a failure, we fallback to English.

This method is called on every page of a website.

public static function detect_locale() {
    if(isset($_SESSION["lang"])){
        $lang = $_SESSION["lang"];
        return $lang;
    }
    if(isset($_SESSION["id"])){
        $user = new User($_SESSION["id"]);
        $lang = $user->get_locale();
        return $lang;
    }
    if($_SERVER["HTTP_HOST"] == "ru.mysupersite.com" || $_SERVER["HTTP_HOST"] == "www.mysupersite.ru"){
        $lang = "ru";
        return $lang;
    }
    if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])){
        $lang = substr($_SERVER["HTTP_ACCEPT_LANGUAGE"], 0, 2);
        return $lang;
    }
    $lang = "en";
    return $lang;
}

I see it as a pretty straightforward solution, but something in the back of my mind says that there might be some flaws. Are there any or am I just paranoid?

Thank you!

share|improve this question
1  
Can you check if the locale is available/valid? If yes then I'd check $lang and only return if it's accepted and otherwise fall through to the subsequent tests. I'd also move the language-from-host detection code to it's own function to allow for easier testing and extension. –  user786653 Nov 9 '11 at 16:53

1 Answer 1

up vote 1 down vote accepted

Your basic hierarchy seems fairly solid. There is just one thing - HTTP_ACCEPT_LANGUAGE is not so simple. I wrote an answer on it here. What follows is the relevant code from that:

// Parse the Accept-Language according to:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
preg_match_all(
   '/([a-z]{1,8})' .       // M1 - First part of language e.g en
   '(-[a-z]{1,8})*\s*' .   // M2 -other parts of language e.g -us
   // Optional quality factor M3 ;q=, M4 - Quality Factor
   '(;\s*q\s*=\s*((1(\.0{0,3}))|(0(\.[0-9]{0,3}))))?/i',
   $_SERVER['HTTP_ACCEPT_LANGUAGE'],
   $langParse);

$langs = $langParse[1]; // M1 - First part of language
$quals = $langParse[4]; // M4 - Quality Factor

$numLanguages = count($langs);
$langArr = array();

for ($num = 0; $num < $numLanguages; $num++)
{
   $newLang = strtoupper($langs[$num]);
   $newQual = isset($quals[$num]) ?
      (empty($quals[$num]) ? 1.0 : floatval($quals[$num])) : 0.0;

   // Choose whether to upgrade or set the quality factor for the
   // primary language.
   $langArr[$newLang] = (isset($langArr[$newLang])) ?
      max($langArr[$newLang], $newQual) : $newQual;
}

// sort list based on value
// langArr will now be an array like: array('EN' => 1, 'ES' => 0.5)
arsort($langArr, SORT_NUMERIC);

// The languages the client accepts in order of preference.
$acceptedLanguages = array_keys($langArr);

// Set the most preferred language that we have a translation for.
foreach ($acceptedLanguages as $preferredLanguage)
{
    if (in_array($preferredLanguage, $websiteLanguages))
    {
       $_SESSION['lang'] = $preferredLanguage;
       return $preferredLanguage;
    }
}

You would need to define website languages or just set the most preferred language.

Also as a very minor point I would change:

$lang = xxx;
return $lang;

To:

return xxx;
share|improve this answer
    
Thank you! That's a sweet idea about more detailed parsing of ACCEPT_LANGUAGE. With the link you gave, always wondered, is there some sort of sacred knowledge behind using $_COOKIE instead of $_SESSION for language setting? –  paulus Nov 11 '11 at 0:10
    
@paulus $_COOKIE is stored by the browser whereas $_SESSION is stored on the server. The different lifetimes might make COOKIE a better choice for language in a lot of situations. This describes it well: buildinternet.com/2010/07/when-to-use-_session-vs-_cookie –  Paul Nov 11 '11 at 2:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.