
Now I am working on a site that claims to be global, naturally and with multilingualism it should be all right.
About how to display information in different languages, there will be no talk here. The conversation will be about how to determine the user's language, and choose the most appropriate language version available on the site.
For those who are too lazy to read - see the
screencast, it really didn’t really work out, so I don’t post it here.
')
And so what we have:
- Php
- The CodeIgniter framework (the class was written for this framework, but it can be used anywhere with minor changes)
Task:
Determine the user's language and if the user is Russian-speaking (Russian, Belarus, Ukrainian full list
here ) we show him the information in Russian. If not then in English.
All this needs to be arranged in the form of a class or function with the ability to quickly set something like links from the user's language to the best language for understanding on the site.
Decision:
To determine the user's language, we use the $ _SERVER superglobal array, or rather, its element $ _SERVER ['HTTP_ACCEPT_LANGUAGE'] in it describes the client's preferences regarding the language. This information is extracted from the Accept-Language HTTP header, which is sent by the client to the server.
In my case it was a string.
ru-ru,ru;q=0.8,en-us;q=0.6,en;q=0.4
This line contains the user's languages that he prefers, and their priorities are expressed in q, if q is not specified for the language, it is assumed that it will be 1. If you try to display it in a less readable form, it looks like this:
Array ( [ru-ru] => 1 [ru] => 0.8 [en-us] => 0.6 [en] => 0.4 )
This shows that I prefer Russian, and in second place I have English.
Languages are written in two formats. The
main language code is “ru” and “en” in my case, which is related to the language standards of
ISO 639And the
main language code - the extended language code in my case is “ru-ru” and “en-us”; here the extended language code indicates the region where the language is used in my country is United States.
At times, there is a misunderstanding with how to mark languages when the ISO code lists contain both two-letter and three-letter codes (sometimes several three-letter codes). Now all valid codes are listed in one
IANA registry , which for a language takes only one value from the ISO lists. If an ISO two-letter code is available, it will be one in the registry. Otherwise, the registry will contain one three-letter code. It will simplify things.
With theory figured out go to the practice:
Let's write the constructor of the class controller:
public function __construct() { if (($list = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']))) { if (preg_match_all('/([az]{1,8}(?:-[az]{1,8})?)(?:;q=([0-9.]+))?/', $list, $list)) { $this->language = array_combine($list[1], $list[2]); foreach ($this->language as $n => $v) $this->language[$n] = $v ? $v : 1; arsort($this->language, SORT_NUMERIC); } } else $this->language = array(); }
Here we process the string returned by $ _SERVER ['HTTP_ACCEPT_LANGUAGE'] so that it turns out an array of the form
Array ( [ru-ru] => 1 [ru] => 0.8 [en-us] => 0.6 [en] => 0.4 )
Sorted in descending order of priority of the language (q value)
Next, create a method that finds the most appropriate language.
The first default language is the default language, the second array of which will be the languages that are on the site, and the values of the link to it from other languages look like this:
$langs=array( 'ru'=>array('ru','be','uk','ky','ab','mo','et','lv'), 'de'=>'de' );
Method code:
public function getBestMatch($default, $langs) { $languages=array(); foreach ($langs as $lang => $alias) { if (is_array($alias)) { foreach ($alias as $alias_lang) { $languages[strtolower($alias_lang)] = strtolower($lang); } }else $languages[strtolower($alias)]=strtolower($lang); } foreach ($this->language as $l => $v) { $s = strtok($l, '-');
The function truncates the format languages the
main language code is the extended language code to the format the
main language code since The need for the English and American versions of the language is unlikely to arise, and if you like, you can always finish writing.
The result of its execution will be the most suitable language of the user, in the
ISO 639 format I transferred English as the default language, and for all languages that are not in the $ langs array,
en will be returned.
Download the library
here.