Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect Browser Language in PHP

I use the following PHP script as index for my website.

This script should include a specific page depending on the browser's language (automatically detected).

This script does not work well with all browsers, so it always includes index_en.php for any detected language (the cause of the problem is most probably an issue with some Accept-Language header not being considered).

Could you please suggest me a more robust solution?

<?php // Open session var session_start(); // views: 1 = first visit; >1 = second visit  // Detect language from user agent browser function lixlpixel_get_env_var($Var) {      if(empty($GLOBALS[$Var]))      {          $GLOBALS[$Var]=(!empty($GLOBALS['_SERVER'][$Var]))?          $GLOBALS['_SERVER'][$Var] : (!empty($GLOBALS['HTTP_SERVER_VARS'][$Var])) ? $GLOBALS['HTTP_SERVER_VARS'][$Var]:'';      } }  function lixlpixel_detect_lang() {      // Detect HTTP_ACCEPT_LANGUAGE & HTTP_USER_AGENT.      lixlpixel_get_env_var('HTTP_ACCEPT_LANGUAGE');      lixlpixel_get_env_var('HTTP_USER_AGENT');       $_AL=strtolower($GLOBALS['HTTP_ACCEPT_LANGUAGE']);      $_UA=strtolower($GLOBALS['HTTP_USER_AGENT']);       // Try to detect Primary language if several languages are accepted.      foreach($GLOBALS['_LANG'] as $K)      {          if(strpos($_AL, $K)===0)          return $K;      }       // Try to detect any language if not yet detected.      foreach($GLOBALS['_LANG'] as $K)      {          if(strpos($_AL, $K)!==false)          return $K;      }      foreach($GLOBALS['_LANG'] as $K)      {          //if(preg_match("/[[( ]{$K}[;,_-)]/",$_UA)) // matching other letters (create an error for seo spyder)          return $K;      }       // Return default language if language is not yet detected.      return $GLOBALS['_DLANG']; }  // Define default language. $GLOBALS['_DLANG']='en';  // Define all available languages. // WARNING: uncomment all available languages  $GLOBALS['_LANG'] = array( 'af', // afrikaans. 'ar', // arabic. 'bg', // bulgarian. 'ca', // catalan. 'cs', // czech. 'da', // danish. 'de', // german. 'el', // greek. 'en', // english. 'es', // spanish. 'et', // estonian. 'fi', // finnish. 'fr', // french. 'gl', // galician. 'he', // hebrew. 'hi', // hindi. 'hr', // croatian. 'hu', // hungarian. 'id', // indonesian. 'it', // italian. 'ja', // japanese. 'ko', // korean. 'ka', // georgian. 'lt', // lithuanian. 'lv', // latvian. 'ms', // malay. 'nl', // dutch. 'no', // norwegian. 'pl', // polish. 'pt', // portuguese. 'ro', // romanian. 'ru', // russian. 'sk', // slovak. 'sl', // slovenian. 'sq', // albanian. 'sr', // serbian. 'sv', // swedish. 'th', // thai. 'tr', // turkish. 'uk', // ukrainian. 'zh' // chinese. );  // Redirect to the correct location. // Example Implementation aff var lang to name file /* echo 'The Language detected is: '.lixlpixel_detect_lang(); // For Demonstration echo "<br />";     */ $lang_var = lixlpixel_detect_lang(); //insert lang var system in a new var for conditional statement /* echo "<br />";      echo $lang_var; // print var for trace  echo "<br />";     */ // Insert the right page iacoording with the language in the browser switch ($lang_var){     case "fr":         //echo "PAGE DE";         include("index_fr.php");//include check session DE         break;     case "it":         //echo "PAGE IT";         include("index_it.php");         break;     case "en":         //echo "PAGE EN";         include("index_en.php");         break;             default:         //echo "PAGE EN - Setting Default";         include("index_en.php");//include EN in all other cases of different lang detection         break; } ?> 
like image 754
GibboK Avatar asked Sep 22 '10 14:09

GibboK


People also ask

How to detect browser language in PHP?

We can detect requesting browser's language using PHP's super global variable $_SERVER . It is a superglobal variable which holds information about headers, paths, and script locations. It is basically an associative array in PHP which has keys like SERVER_NAME, SERVER_ADDR, REQUEST_METHOD , etc.

How does laravel know language?

First you set $availableLangs the array of the available languages in your app, you may use config\app. php instead of initializing the array in the middleware as I did. If the first language is available in the request language data, it sets the locale, if not, it will search the next one, and so on.


2 Answers

why dont you keep it simple and clean

<?php     $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);     $acceptLang = ['fr', 'it', 'en'];      $lang = in_array($lang, $acceptLang) ? $lang : 'en';     require_once "index_{$lang}.php";   ?> 
like image 144
Pramendra Gupta Avatar answered Sep 17 '22 14:09

Pramendra Gupta


Accept-Language is a list of weighted values (see q parameter). That means just looking at the first language does not mean it’s also the most preferred; in fact, a q value of 0 means not acceptable at all.

So instead of just looking at the first language, parse the list of accepted languages and available languages and find the best match:

// parse list of comma separated language tags and sort it by the quality value function parseLanguageList($languageList) {     if (is_null($languageList)) {         if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {             return array();         }         $languageList = $_SERVER['HTTP_ACCEPT_LANGUAGE'];     }     $languages = array();     $languageRanges = explode(',', trim($languageList));     foreach ($languageRanges as $languageRange) {         if (preg_match('/(\*|[a-zA-Z0-9]{1,8}(?:-[a-zA-Z0-9]{1,8})*)(?:\s*;\s*q\s*=\s*(0(?:\.\d{0,3})|1(?:\.0{0,3})))?/', trim($languageRange), $match)) {             if (!isset($match[2])) {                 $match[2] = '1.0';             } else {                 $match[2] = (string) floatval($match[2]);             }             if (!isset($languages[$match[2]])) {                 $languages[$match[2]] = array();             }             $languages[$match[2]][] = strtolower($match[1]);         }     }     krsort($languages);     return $languages; }  // compare two parsed arrays of language tags and find the matches function findMatches($accepted, $available) {     $matches = array();     $any = false;     foreach ($accepted as $acceptedQuality => $acceptedValues) {         $acceptedQuality = floatval($acceptedQuality);         if ($acceptedQuality === 0.0) continue;         foreach ($available as $availableQuality => $availableValues) {             $availableQuality = floatval($availableQuality);             if ($availableQuality === 0.0) continue;             foreach ($acceptedValues as $acceptedValue) {                 if ($acceptedValue === '*') {                     $any = true;                 }                 foreach ($availableValues as $availableValue) {                     $matchingGrade = matchLanguage($acceptedValue, $availableValue);                     if ($matchingGrade > 0) {                         $q = (string) ($acceptedQuality * $availableQuality * $matchingGrade);                         if (!isset($matches[$q])) {                             $matches[$q] = array();                         }                         if (!in_array($availableValue, $matches[$q])) {                             $matches[$q][] = $availableValue;                         }                     }                 }             }         }     }     if (count($matches) === 0 && $any) {         $matches = $available;     }     krsort($matches);     return $matches; }  // compare two language tags and distinguish the degree of matching function matchLanguage($a, $b) {     $a = explode('-', $a);     $b = explode('-', $b);     for ($i=0, $n=min(count($a), count($b)); $i<$n; $i++) {         if ($a[$i] !== $b[$i]) break;     }     return $i === 0 ? 0 : (float) $i / count($a); }  $accepted = parseLanguageList($_SERVER['HTTP_ACCEPT_LANGUAGE']); var_dump($accepted); $available = parseLanguageList('en, fr, it'); var_dump($available); $matches = findMatches($accepted, $available); var_dump($matches); 

If findMatches returns an empty array, no match was found and you can fall back on the default language.

like image 37
Gumbo Avatar answered Sep 20 '22 14:09

Gumbo