Функция cot_lang_determine в Cotonti
Описание функции.
Функция cot_lang_determine() предназначена для определения языка, который должен быть использован на сайте, исходя из заголовка HTTP_ACCEPT_LANGUAGE, который передается браузером пользователя при запросе страницы. Этот заголовок указывает предпочтения пользователя по языкам для локализации.
/**
* Returns a exists language from HTTP_ACCEPT_LANGUAGE
*
* @return string
*/
function cot_lang_determine()
{
global $cfg;
if (($list = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])))
{
if (preg_match_all('/([a-z]{1,8}(?:-[a-z]{1,8})?)(?:;q=([0-9.]+))?/', $list, $list))
{
$language = array_combine($list[1], $list[2]);
//
foreach ($language as $n => $v)
{
$language[$n] = $v ? $v : 1;
}
arsort($language, SORT_NUMERIC);
foreach ($language as $n => $v)
{
if (@file_exists($cfg['lang_dir']."/$n/main.$n.lang.php"))
{
return $n;
}
}
}
}
return 'en';
}
Давай разберемся, что происходит в функции cot_lang_determine().
Пошаговый разбор и анализ функции cot_lang_determine
Получение и обработка HTTP_ACCEPT_LANGUAGE:
if (($list = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE'])))
Функция сначала пытается получить значение заголовка HTTP_ACCEPT_LANGUAGE, который содержит список языков, предпочтительных для пользователя. Заголовок переводится в нижний регистр для унификации.
Использование регулярного выражения для парсинга заголовка:
if (preg_match_all('/([a-z]{1,8}(?:-[a-z]{1,8})?)(?:;q=([0-9.]+))?/', $list, $list))
Регулярное выражение используется для разбора строки из заголовка. Оно ищет языковые теги (например, en, fr, de) и может учитывать предпочтение качества (например, en;q=0.9, где число после q указывает на приоритет). Эти данные извлекаются и сохраняются в массив $list.
Создание ассоциативного массива для языков:
$language = array_combine($list[1], $list[2]);
Из распарсенной строки формируется ассоциативный массив $language, где ключами являются языковые коды (например, en, fr), а значениями — качество (q), которое обозначает предпочтительность этого языка.
Корректировка значений массива:
foreach ($language as $n => $v)
{
$language[$n] = $v ? $v : 1;
}
Если качество языка не указано, оно устанавливается как 1 по умолчанию (максимальное значение). Это необходимо для обработки случаев, когда качество не указано (например, просто en вместо en;q=1).
Сортировка по приоритету (качеству):
arsort($language, SORT_NUMERIC);
Массив сортируется по значению в убывающем порядке, чтобы сначала рассматривать более предпочтительные языки.
Проверка наличия файла для каждого языка:
foreach ($language as $n => $v)
{
if (@file_exists($cfg['lang_dir']."/$n/main.$n.lang.php"))
{
return $n;
}
}
Далее функция проверяет, существует ли файл с языковым ресурсом для каждого из языков в отсортированном списке
(например, en/main.en.lang.php или fr/main.fr.lang.php).
Если файл найден, возвращается код этого языка.
Возврат языка по умолчанию, если файл не найден:
return 'en';
Если ни один из языков не соответствует, возвращается язык по умолчанию — английский ('en').
Резюме
Функция cot_lang_determine() анализирует язык, предпочтительный для пользователя, на основе заголовка HTTP_ACCEPT_LANGUAGE. Она пытается найти файл с языковыми ресурсами для одного из предпочтительных языков, начиная с самого приоритетного, и возвращает код языка. Если подходящий файл не найден, возвращается язык по умолчанию — 'en'.
Функция полезна для динамического выбора языка, исходя из предпочтений пользователя или его региона.
Пример применения функции cot_lang_determine в Cotonti.
Ниже фрагмент кода использует функцию cot_lang_determine для выбора языка в процессе установки (installer), разберем его по шагам:
// Installer language selection support
if (empty($_SESSION['cot_inst_lang'])) {
$lang = cot_import('lang', 'P', 'ALP');
if (empty($lang)) {
$lang = cot_lang_determine();
}
} else {
$lang = $_SESSION['cot_inst_lang'];
}
Контекст функции cot_lang_determine внутри условия выбора языка установки Cotonti CMF:
Задача кода — определить, какой язык использовать для установки.
Если язык уже сохранен в сессии ($_SESSION['cot_inst_lang']), используется именно он.
Если язык отсутствует в сессии, проверяется язык, переданный через POST-запрос.
Если язык не передан явно, система автоматически определяет подходящий язык на основе HTTP_ACCEPT_LANGUAGE (с помощью cot_lang_determine).
Подробный разбор условия, которое содержит функцию cot_lang_determine:
1. Проверка сохраненного языка в сессии:
if (empty($_SESSION['cot_inst_lang'])) {
Если язык не был ранее сохранен в сессии ($_SESSION['cot_inst_lang']), переходим к попытке определить язык другим способом.
2. Получение языка из POST-запроса:
$lang = cot_import('lang', 'P', 'ALP');
Здесь используется функция cot_import для получения значения параметра lang из POST-запроса.
'lang' — имя параметра.'P' — тип данных, означает, что ищем параметр только в POST-запросе.'ALP' — тип фильтрации, допускаются только алфавитные символы.
Если lang не был передан через POST, значение переменной $lang остается пустым.
3. Определение языка через cot_lang_determine:
if (empty($lang)) {
$lang = cot_lang_determine();
}
Если язык не был передан явно, используется функция cot_lang_determine.
Она анализирует заголовок HTTP_ACCEPT_LANGUAGE и возвращает первый подходящий язык, для которого в системе есть соответствующий файл (например, en, fr, ru).
4. Альтернативный сценарий: сохраненный язык:
} else {
$lang = $_SESSION['cot_inst_lang'];
}
Если язык был ранее сохранен в сессии ($_SESSION['cot_inst_lang']), он используется напрямую. Это позволяет сохранять выбранный пользователем язык между шагами установки.
Роль cot_lang_determine в данном коде:
Функция cot_lang_determine используется как запасной механизм, чтобы:
Автоматически определить язык пользователя, если он не указан явно (ни в POST-запросе, ни в сессии).
Предоставить пользователю подходящий интерфейс на основе предпочтений браузера (HTTP_ACCEPT_LANGUAGE).
Таким образом, она играет ключевую роль в обеспечении "умного" выбора языка в отсутствие явного указания.
Comments (0)
Content author
Offline
Administrator
Last logged: 2026-07-05 18:32
- Page published: 2025-01-22 13:56
- Last update: 2025-01-22 14:05