setlocale()
Статья о функции PHP setlocale(), которая используется для установки текущей локали и культурно-специфических правил форматирования.
Функция PHP setlocale() устанавливает текущую локаль для скрипта — набор культурно-специфических правил, определяющих порядок сортировки текста, форматирования чисел и валюты, а также написания дат. Локаль идентифицируется строкой вида en_US (американский английский) или de_DE (немецкий), как правило, в сочетании с кодировкой символов, например .utf8.
Функция setlocale() нужна тогда, когда одна кодовая база должна выдавать вывод, воспринимаемый как «родной» в разных странах: 1,234.56 для американского пользователя, но 1.234,56 для немецкого, January вместо Januar и т. д.
Синтаксис
setlocale(int $category, string $locale, string ...$locales): string|falseТакже можно передать единственный массив локалей вместо списка:
setlocale(int $category, array $locale): string|falseПараметры
-
$category— группа локально-зависимого поведения, которую нужно изменить. Передаётся одна из константLC_*:Константа Влияет на LC_ALLВсе категории одновременно LC_COLLATEСравнение строк и сортировку (см. strcoll())LC_CTYPEКлассификацию символов и преобразование регистра LC_MONETARYФорматирование валюты (см. money_format())LC_NUMERICРазделитель дробной части чисел LC_TIMEФорматирование даты и времени (см. strftime())LC_MESSAGESФорматирование системных сообщений (недоступно в Windows) -
$locale— строка локали, которую нужно применить, например'en_US.utf8'. Три специальных значения:""(пустая строка) — использовать локаль из переменных окружения сервера."0"— не менять ничего; просто вернуть текущее значение для данной категории.null— то же, что и"0".
-
...$locales— необязательные запасные варианты. PHP перебирает имена по порядку и применяет первое, установленное в операционной системе.
При успехе возвращает имя установленной локали, при неудаче — false, если ни одна из запрошенных локалей недоступна.
Базовый пример
<?php
$result = setlocale(LC_ALL, 'en_US.utf8');
if ($result !== false) {
echo "Locale set to: $result";
} else {
echo "Requested locale is not installed.";
}
?>setlocale() возвращает строку новой локали при успехе или false при неудаче, поэтому всегда проверяйте возвращаемое значение — отсутствующая локаль завершается молча и оставляет форматирование некорректным, не генерируя исключения.
Указание запасных вариантов
Имена локалей различаются в зависимости от операционной системы (en_US.utf8 в Linux, English_United States.1252 в Windows). Перечисление нескольких имён позволяет скрипту работать везде — PHP использует первое установленное совпадение:
<?php
$locale = setlocale(
LC_ALL,
'en_US.UTF-8', // Linux / macOS
'en_US.utf8',
'English_United States.1252' // Windows
);
echo $locale ?: 'No English locale available';
?>Почему локаль важна: форматирование чисел
После установки LC_NUMERIC (или LC_ALL) функции, учитывающие локаль, выдают культурно-специфический вывод. В примере ниже разделители дробной части и тысяч следуют немецким соглашениям:
<?php
setlocale(LC_ALL, 'de_DE.utf8', 'de_DE', 'German_Germany.1252');
$info = localeconv();
echo $info['decimal_point']; // ,
echo "\n";
echo $info['thousands_sep']; // .
?>localeconv() считывает числовые и денежные правила активной локали, что является наиболее надёжным способом форматирования чисел вручную. Обратите внимание, что number_format() в PHP не учитывает локаль — разделители передаются ей явно.
Типичные подводные камни
- Локаль должна быть установлена на сервере.
setlocale()успешно выполняется только для локалей, известных ОС. На сервере Debian/Ubuntu может потребоватьсяlocale-gen de_DE.UTF-8 && update-locale. - Это глобальная настройка процесса, не потокобезопасная. Параметр влияет на весь PHP-процесс, поэтому избегайте его изменения одновременно в многопоточных SAPI.
- Она не влияет на
echoилиprintf()для чисел с плавающей точкой. Используйтеsprintf()с осторожностью; десятичная точка локали может удивить функции, формирующие SQL или JSON. Сбрасывайте настройку черезsetlocale(LC_NUMERIC, 'C')вокруг такого кода. money_format()удалена в PHP 8.0. Для работы с валютой предпочтительнее классNumberFormatterиз расширенияintl.