{lang: ‘ru’}

php определение языка, исходники phpПриветствую Вас на моем блоге! В этот раз я покажу Вам, как можно определить язык интерфейса пользователя с помощью PHP. На мой взгляд, определение языка является одной из важных особенностей любого серьезного мультиязычного веб-сайта. Как минимум — вы можете установить необходимый язык интерфейса веб-сайта для посетителей. Наш скрипт покажет Вам один из возможных языков (в зависимости от настройки вашего браузера). Готовы? Тогда начнем.

Demo Исходники

Шаг 1. PHP

Для начала нужно задать массив со значениями языков и их кодов.

langs.php

<?php
// всевозможные языковые коды
$aLanguages = array(
    'aa' => 'Afar',
    'ab' => 'Abkhaz',
    'ae' => 'Avestan',
    'af' => 'Afrikaans',
    'ak' => 'Akan',
    'am' => 'Amharic',
    'an' => 'Aragonese',
    'ar' => 'Arabic',
    'as' => 'Assamese',
    'av' => 'Avaric',
    'ay' => 'Aymara',
    'az' => 'Azerbaijani',
    'ba' => 'Bashkir',
    'be' => 'Belarusian',
    'bg' => 'Bulgarian',
    'bh' => 'Bihari',
    'bi' => 'Bislama',
    'bm' => 'Bambara',
    'bn' => 'Bengali',
    'bo' => 'Tibetan Standard, Tibetan, Central',
    'br' => 'Breton',
    'bs' => 'Bosnian',
    'ca' => 'Catalan; Valencian',
    'ce' => 'Chechen',
    'ch' => 'Chamorro',
    'co' => 'Corsican',
    'cr' => 'Cree',
    'cs' => 'Czech',
    'cu' => 'Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic',
    'cv' => 'Chuvash',
    'cy' => 'Welsh',
    'da' => 'Danish',
    'de' => 'German',
    'dv' => 'Divehi; Dhivehi; Maldivian;',
    'dz' => 'Dzongkha',
    'ee' => 'Ewe',
    'el' => 'Greek, Modern',
    'en' => 'English',
    'eo' => 'Esperanto',
    'es' => 'Spanish; Castilian',
    'et' => 'Estonian',
    'eu' => 'Basque',
    'fa' => 'Persian',
    'ff' => 'Fula; Fulah; Pulaar; Pular',
    'fi' => 'Finnish',
    'fj' => 'Fijian',
    'fo' => 'Faroese',
    'fr' => 'French',
    'fy' => 'Western Frisian',
    'ga' => 'Irish',
    'gd' => 'Scottish Gaelic; Gaelic',
    'gl' => 'Galician',
    'gn' => 'GuaranA­',
    'gu' => 'Gujarati',
    'gv' => 'Manx',
    'ha' => 'Hausa',
    'he' => 'Hebrew (modern)',
    'hi' => 'Hindi',
    'ho' => 'Hiri Motu',
    'hr' => 'Croatian',
    'ht' => 'Haitian; Haitian Creole',
    'hu' => 'Hungarian',
    'hy' => 'Armenian',
    'hz' => 'Herero',
    'ia' => 'Interlingua',
    'id' => 'Indonesian',
    'ie' => 'Interlingue',
    'ig' => 'Igbo',
    'ii' => 'Nuosu',
    'ik' => 'Inupiaq',
    'io' => 'Ido',
    'is' => 'Icelandic',
    'it' => 'Italian',
    'iu' => 'Inuktitut',
    'ja' => 'Japanese (ja)',
    'jv' => 'Javanese (jv)',
    'ka' => 'Georgian',
    'kg' => 'Kongo',
    'ki' => 'Kikuyu, Gikuyu',
    'kj' => 'Kwanyama, Kuanyama',
    'kk' => 'Kazakh',
    'kl' => 'Kalaallisut, Greenlandic',
    'km' => 'Khmer',
    'kn' => 'Kannada',
    'ko' => 'Korean',
    'kr' => 'Kanuri',
    'ks' => 'Kashmiri',
    'ku' => 'Kurdish',
    'kv' => 'Komi',
    'kw' => 'Cornish',
    'ky' => 'Kirghiz, Kyrgyz',
    'la' => 'Latin',
    'lb' => 'Luxembourgish, Letzeburgesch',
    'lg' => 'Luganda',
    'li' => 'Limburgish, Limburgan, Limburger',
    'ln' => 'Lingala',
    'lo' => 'Lao',
    'lt' => 'Lithuanian',
    'lu' => 'Luba-Katanga',
    'lv' => 'Latvian',
    'mg' => 'Malagasy',
    'mh' => 'Marshallese',
    'mi' => 'Maori',
    'mk' => 'Macedonian',
    'ml' => 'Malayalam',
    'mn' => 'Mongolian',
    'mr' => 'Marathi',
    'ms' => 'Malay',
    'mt' => 'Maltese',
    'my' => 'Burmese',
    'na' => 'Nauru',
    'nb' => 'Norwegian Bokmal',
    'nd' => 'North Ndebele',
    'ne' => 'Nepali',
    'ng' => 'Ndonga',
    'nl' => 'Dutch',
    'nn' => 'Norwegian Nynorsk',
    'no' => 'Norwegian',
    'nr' => 'South Ndebele',
    'nv' => 'Navajo, Navaho',
    'ny' => 'Chichewa; Chewa; Nyanja',
    'oc' => 'Occitan',
    'oj' => 'Ojibwe, Ojibwa',
    'om' => 'Oromo',
    'or' => 'Oriya',
    'os' => 'Ossetian, Ossetic',
    'pa' => 'Panjabi, Punjabi',
    'pi' => 'Pali',
    'pl' => 'Polish',
    'ps' => 'Pashto, Pushto',
    'pt' => 'Portuguese',
    'qu' => 'Quechua',
    'rm' => 'Romansh',
    'rn' => 'Kirundi',
    'ro' => 'Romanian, Moldavian, Moldovan',
    'ru' => 'Russian',
    'rw' => 'Kinyarwanda',
    'sa' => 'Sanskrit',
    'sc' => 'Sardinian',
    'sd' => 'Sindhi',
    'se' => 'Northern Sami',
    'sg' => 'Sango',
    'si' => 'Sinhala, Sinhalese',
    'sk' => 'Slovak',
    'sl' => 'Slovene',
    'sm' => 'Samoan',
    'sn' => 'Shona',
    'so' => 'Somali',
    'sq' => 'Albanian',
    'sr' => 'Serbian',
    'ss' => 'Swati',
    'st' => 'Southern Sotho',
    'su' => 'Sundanese',
    'sv' => 'Swedish',
    'sw' => 'Swahili',
    'ta' => 'Tamil',
    'te' => 'Telugu',
    'tg' => 'Tajik',
    'th' => 'Thai',
    'ti' => 'Tigrinya',
    'tk' => 'Turkmen',
    'tl' => 'Tagalog',
    'tn' => 'Tswana',
    'to' => 'Tonga (Tonga Islands)',
    'tr' => 'Turkish',
    'ts' => 'Tsonga',
    'tt' => 'Tatar',
    'tw' => 'Twi',
    'ty' => 'Tahitian',
    'ug' => 'Uighur, Uyghur',
    'ua' => 'Ukrainian',
    'ur' => 'Urdu',
    'uz' => 'Uzbek',
    've' => 'Venda',
    'vi' => 'Vietnamese',
    'vo' => 'Volapuk',
    'wa' => 'Walloon',
    'wo' => 'Wolof',
    'xh' => 'Xhosa',
    'yi' => 'Yiddish',
    'yo' => 'Yoruba',
    'za' => 'Zhuang, Chuang',
    'zh' => 'Chinese',
    'zu' => 'Zulu',
);
?>

Функция определения языка находится в главном файле

index.php

function tryToFindLang($aLanguages, $sWhere, $sDefaultLang) {

    // установить текущий язык, как язык по умолчанию
    $sLanguage = $sDefaultLang;

    // начальное значение качества
    $fBetterQuality = 0;

    // поиск по всем соответствующим параметрам
    preg_match_all("/([[:alpha:]]{1,8})(-([[:alpha:]|-]{1,8}))?(s*;s*qs*=s*(1.0{0,3}|0.d{0,3}))?s*(,|$)/i", $sWhere, $aMatches, PREG_SET_ORDER);
    foreach ($aMatches as $aMatch) {

        // получить префикс языка
        $sPrefix = strtolower ($aMatch[1]);

        // подготовить временный язык
        $sTempLang = (empty($aMatch[3])) ? $sPrefix : $sPrefix . '-' . strtolower ($aMatch[3]);

        // получить качество языка (если есть)
        $fQuality = (empty($aMatch[5])) ? 1.0 : floatval($aMatch[5]);

        if ($sTempLang) {

            // определение предпочтительного языка
            if ($fQuality > $fBetterQuality && in_array($sTempLang, array_keys($aLanguages))) {

                // установить временный язык, как язык по умолчанию и обновить значения качества
                $sLanguage = $sTempLang;
                $fBetterQuality = $fQuality;
            } elseif (($fQuality*0.9) > $fBetterQuality && in_array($sPrefix, array_keys($aLanguages))) {

                // установить язык по умолчанию, как значение префикса и обновить значения качества
                $sLanguage = $sPrefix;
                $fBetterQuality = $fQuality * 0.9;
            }
        }
    }
    return $sLanguage;
}

Основная идея — проанализировать глобальные переменные: $ _SERVER ['HTTP_ACCEPT_LANGUAGE'], как мы знаем — эта переменная содержит строку типа “en-US,en;q=0.8″. Получив значение из заголовков запроса мы устанавливаем его по умолчанию.

Хочу обратить внимание на такую переменную, как качество (quality). На мой взгляд здесь может возникнуть много вопросов. Большинство веб-браузеров отправляют «Accept-Language» HTTP- заголовки, которые определяют язык пользователя. Этот заголовок будет выглядеть примерно так:

Accept-Language: EN, FR, Q = 0,9, DE, Q = 0,8

Это означает, что каждый язык имеет значение»q-value», которое определяет силу предпочтений. Если q-value не задано, то предполагается, что оно будет равно 1.0. В примере английский будет иметь значение 1.0, французский 0.9 и немецкий 0.8. Q-value не просто относительное предпочтение; То есть изменение значения от 0,8 до 0,6 может изменить на каком языке будет получен ответ от сервера. В итоге будет выбран язык с самым высоким результирующим значением.

И так, переходим к самому главному. Получение возможных языков и вызов функции:

// получить все возможные коды языков
require_once('langs.php');
$sLanguage = tryToFindLang($aLanguages, $_SERVER['HTTP_ACCEPT_LANGUAGE'], 'en');

После этого переменная $sLanguage будет содержать в себе определенный язык.

Следует обратить внимание на то, что этот способ определения языка не идеален. Если у русскоязычного пользователя будет установлен англоязычный браузер, то скрипт выберет английский язык. Но в большинстве случаев этого способа достаточно.

Итоги

В этот раз мы сделали полезный PHP скрипт, с помощью которого определение языка пользователя становится чуточку проще. Используйте этот скрипт в своих проектах. Удачи в работе!


Получайте новые статьи блога прямо себе на почту