In order to improve the user experience on a website, it's important to display information in a format that is acceptable in the user's locale. Locale is a generic term used to indicate an area of the world. An effort in the I.T. community has been made to codify locales using a two-part designation consisting of codes for both language and country. But when a person visits your website, how do you know their locale? Probably the most useful technique involves examining the HTTP language header.
Application\I18n\Locale. We will have this class extend an existing class, Locale, which is part of the PHP Intl extension.namespace Application\I18n;
use Locale as PhpLocale;
class Locale extends PhpLocale
{
const FALLBACK_LOCALE = 'en';
// some code
}phpinfo(INFO_VARIABLES). Be sure to disable this function immediately after testing as it gives away too much information to potential attackers:<?php phpinfo(INFO_VARIABLES); ?>
$_SERVER['HTTP_ACCEPT_LANGUAGE']. The value will take this general form: ll-CC,rl;q=0.n, ll-CC,rl;q=0.n, as defined in this table:|
Abbreviation |
Meaning |
|---|---|
|
|
Two-character lowercase code representing the language. |
|
|
Separates language from country in the locale code |
|
| |
|
|
Separates locale code from fallback root locale code (usually the same as the language code). |
|
|
Two-character lowercase code representing the suggested root locale. |
|
|
Separates locale information from quality. If quality is missing, default is |
|
|
Quality. |
|
|
Some value between 0.00 and 1.0. Multiply this value by 100 to get the percentage of probability that this is the actual language preferred by this visitor. |
Locale class has a method, acceptFromHttp(), which reads the Accept-language header string and gives us the desired setting:protected $localeCode;
public function setLocaleCode($acceptLangHeader)
{
$this->localeCode = $this->acceptFromHttp($acceptLangHeader);
}get AcceptLanguage() method returns the value from $_SERVER['HTTP_ACCEPT_LANGUAGE']:public function getAcceptLanguage()
{
return $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? self::FALLBACK_LOCALE;
}
public function getLocaleCode()
{
return $this->localeCode;
}public function __construct($localeString = NULL)
{
if ($localeString) {
$this->setLocaleCode($localeString);
} else {
$this->setLocaleCode($this->getAcceptLanguage());
}
}Even though a visitor appears to accept one or more languages, that visitor does not necessarily want contents in the language/locale indicated by their browser. Accordingly, although you can certainly set the locale given this information, you should also provide them with a static list of alternative languages.
In this illustration, let's take three examples:
fr-FRda, en-gb;q=0.8, en;q=0.7Place the code from steps 1 to 6 into a file, Locale.php, which is in the Application\I18n folder.
Next, create a file, chap_08_getting_locale_from_browser.php, which sets up autoloading and uses the new class:
<?php require __DIR__ . '/../Application/Autoload/Loader.php'; Application\Autoload\Loader::init(__DIR__ . '/..'); use Application\I18n\Locale;
Now you can define an array with the three test locale strings:
$locale = [NULL, 'fr-FR', 'da, en-gb;q=0.8, en;q=0.7'];
Finally, loop through the three locale strings, creating instances of the new class. Echo the value returned from getLocaleCode() to see what choice was made:
echo '<table>';
foreach ($locale as $code) {
$locale = new Locale($code);
echo '<tr>
<td>' . htmlspecialchars($code) . '</td>
<td>' . $locale->getLocaleCode() . '</td>
</tr>';
}
echo '</table>';Here is the result (with a little bit of styling):

Locale class, see http://php.net/manual/en/class.locale.phpAccept-Language header, see section 14.4 of RFC 2616: https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html