{"id":28834657,"url":"https://github.com/bermudaphp/polyglot","last_synced_at":"2026-03-06T20:31:55.719Z","repository":{"id":294740133,"uuid":"987929578","full_name":"bermudaphp/polyglot","owner":"bermudaphp","description":"A powerful, flexible internationalization (i18n) and localization (l10n) library for PHP 8.4+ applications with support for ICU message formatting, pluralization, caching, and more.","archived":false,"fork":false,"pushed_at":"2025-05-22T13:28:19.000Z","size":208,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-20T17:47:13.796Z","etag":null,"topics":["i18n","icu","internationalization","intl","localization","php84","translation"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bermudaphp.png","metadata":{"files":{"readme":"README.RU.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-21T19:55:39.000Z","updated_at":"2025-05-22T13:28:23.000Z","dependencies_parsed_at":"2025-05-21T21:15:31.178Z","dependency_job_id":"1312036a-a526-4780-ab8e-bf79fda7d588","html_url":"https://github.com/bermudaphp/polyglot","commit_stats":null,"previous_names":["bermudaphp/polyglot"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bermudaphp/polyglot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bermudaphp%2Fpolyglot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bermudaphp%2Fpolyglot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bermudaphp%2Fpolyglot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bermudaphp%2Fpolyglot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bermudaphp","download_url":"https://codeload.github.com/bermudaphp/polyglot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bermudaphp%2Fpolyglot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30196173,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["i18n","icu","internationalization","intl","localization","php84","translation"],"created_at":"2025-06-19T09:41:37.885Z","updated_at":"2026-03-06T20:31:55.677Z","avatar_url":"https://github.com/bermudaphp.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Polyglot\n\n[![PHP Version Require](https://img.shields.io/badge/php-%3E%3D8.4-brightgreen.svg)](https://php.net/)\n[![GitHub Tests](https://img.shields.io/github/actions/workflow/status/bermudaphp/polyglot/tests.yml?branch=master\u0026label=tests)](https://github.com/bermudaphp/polyglot/actions/workflows/tests.yml)\n[![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Shelamkoff/fa30b7e036077063fbed756e01a91934/raw/polyglot-coverage.json)](https://github.com/bermudaphp/polyglot/actions/workflows/tests.yml)\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/bermudaphp/polyglot.svg)](https://packagist.org/packages/bermudaphp/polyglot)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/bermudaphp/polyglot/blob/master/LICENSE)\n\nPolyglot — это мощная и гибкая библиотека для интернационализации (i18n) и локализации (l10n) PHP 8.4+ приложений с поддержкой форматирования сообщений ICU, множественного числа, кэширования и многого другого.\n\n[Read documentation in English (Документация на английском)](README.md)\n\n## Содержание\n\n- [Установка](#установка)\n- [Базовое использование](#базовое-использование)\n- [Ключевые концепции](#ключевые-концепции)\n- [Создание Translator](#создание-translator)\n- [Локали](#локали)\n- [Файлы переводов](#файлы-переводов)\n- [Множественное число](#множественное-число)\n- [Формат сообщений ICU](#формат-сообщений-icu)\n  - [Подстановка параметров](#подстановка-параметров)\n  - [Форматирование чисел](#форматирование-чисел)\n  - [Форматирование дат](#форматирование-дат)\n  - [Множественное число](#множественное-число-1)\n  - [Выбор по параметру (Select)](#выбор-по-параметру-select)\n  - [Вложенное форматирование](#вложенное-форматирование)\n- [Построители сообщений](#построители-сообщений)\n  - [Построитель сообщений ICU](#построитель-сообщений-icu)\n  - [Построитель множественного числа](#построитель-множественного-числа)\n  - [Построитель выбора](#построитель-выбора)\n- [Кэширование](#кэширование)\n- [Определение локали](#определение-локали)\n- [PSR-15 Middleware](#psr-15-middleware)\n- [Лицензия](#лицензия)\n\n## Установка\n\n```bash\ncomposer require bermudaphp/polyglot\n```\n\n## Базовое использование\n\n```php\n// Создание экземпляра I18n с использованием фабрики\n$i18n = I18nFactory::create('/путь/к/переводам', 'ru', 'en');\n\n// Базовый перевод\necho $i18n-\u003etranslate('welcome'); // \"Добро пожаловать!\"\n\n// Перевод с параметрами\necho $i18n-\u003etranslate('greeting', ['name' =\u003e 'Иван']); // \"Привет, Иван!\"\n\n// Перевод с множественным числом\necho $i18n-\u003etranslatePlural('items', 1); // \"У вас 1 товар\"\necho $i18n-\u003etranslatePlural('items', 5); // \"У вас 5 товаров\"\n\n// Сокращенные методы\necho $i18n-\u003et('welcome');\necho $i18n-\u003etp('items', 3);\n\n// Изменение локали\n$i18n-\u003esetLocale('en');\necho $i18n-\u003et('welcome'); // \"Welcome!\"\n```\n\n## Ключевые концепции\n\nPolyglot использует несколько ключевых концепций:\n\n- **Локаль**: Идентифицирует конкретный язык и регион (например, 'ru_RU', 'en_US')\n- **Домен**: Группирует связанные переводы (например, 'messages', 'errors', 'admin')\n- **Ключ перевода**: Уникальный идентификатор для переводимой строки\n- **Запасная локаль**: Используется, когда перевод отсутствует в основной локали\n- **Множественное число**: Различные формы слов в зависимости от количества (например, \"1 товар\" vs \"5 товаров\")\n- **Формат ICU**: Формат сообщений International Components for Unicode для сложных переводов\n\n## Создание Translator\n\nСамый простой способ создать переводчик — использовать фабрику:\n\n```php\nuse Bermuda\\Polyglot\\I18nFactory;\n\n$i18n = I18nFactory::create(\n    resourcesPath: '/путь/к/переводам',\n    defaultLocale: 'ru',\n    fallbackLocale: 'en',\n    availableLocales: ['ru', 'en', 'de', 'fr'],\n    cache: null // Опциональная реализация кэша\n);\n```\n\nДля большего контроля можно создать компоненты вручную:\n\n```php\nuse Bermuda\\Polyglot\\Translator;\nuse Bermuda\\Polyglot\\Loader\\PhpArrayMessageLoader;\nuse Bermuda\\Polyglot\\Formatter\\IcuMessageFormatter;\nuse Bermuda\\Polyglot\\PluralRule\\CldrPluralRuleProvider;\nuse Bermuda\\Polyglot\\Cache\\InMemoryCache;\n\n// Создание загрузчика\n$loader = new PhpArrayMessageLoader('/путь/к/переводам');\n\n// Создание форматтера\n$formatter = new IcuMessageFormatter(new CldrPluralRuleProvider());\n\n// Создание провайдера правил множественного числа\n$pluralRuleProvider = new CldrPluralRuleProvider();\n\n// Создание кэша (опционально)\n$cache = new InMemoryCache();\n\n// Создание переводчика\n$translator = new Translator(\n    locale: 'ru',\n    fallbackLocale: 'en',\n    loader: $loader,\n    formatter: $formatter,\n    pluralRuleProvider: $pluralRuleProvider,\n    cache: $cache\n);\n\n// Создание экземпляра I18n\n$i18n = new I18n($translator);\n```\n\n## Локали\n\nPolyglot предоставляет несколько способов работы с кодами локалей:\n\n1. Как простые строки ('ru', 'ru_RU', 'en_US')\n2. Используя типизированный enum `LocaleEnum`\n3. Используя value object `Locale`\n\n### LocaleEnum\n\n```php\nuse Bermuda\\Polyglot\\LocaleEnum;\n\n$locale = LocaleEnum::RUSSIAN_RU;\n$i18n-\u003esetLocale($locale);\n\n// Получение кода языка\n$language = $locale-\u003egetLanguageCode(); // 'ru'\n\n// Получение кода региона\n$region = $locale-\u003egetRegionCode(); // 'RU'\n\n// Создание из строки\n$locale = LocaleEnum::fromString('ru-RU'); // Работает как с 'ru-RU', так и с 'ru_RU'\n```\n\n### Объект Locale\n\n```php\nuse Bermuda\\Polyglot\\Locale;\n\n$locale = new Locale('ru_RU');\n\n// Доступ к компонентам\necho $locale-\u003elanguage; // 'ru'\necho $locale-\u003eregion;   // 'RU'\necho $locale-\u003evariant;  // null\n\n// Преобразование в строку\necho $locale; // 'ru_RU'\n\n// Получение запасных локалей\n$fallbacks = $locale-\u003egetFallbacks(); // ['ru']\n```\n\n## Файлы переводов\n\nPolyglot поддерживает несколько форматов файлов переводов:\n\n### PHP Array файлы\n\n```php\n// /путь/к/переводам/ru/messages.php\nreturn [\n    'welcome' =\u003e 'Добро пожаловать!',\n    'greeting' =\u003e 'Привет, {name}!',\n    'items' =\u003e [\n        'one' =\u003e 'У вас {count} товар',\n        'few' =\u003e 'У вас {count} товара',\n        'many' =\u003e 'У вас {count} товаров',\n        'other' =\u003e 'У вас {count} товаров'\n    ],\n    'user' =\u003e [\n        'greeting' =\u003e 'С возвращением, {name}!',\n        'profile' =\u003e [\n            'title' =\u003e 'Профиль пользователя'\n        ]\n    ]\n];\n```\n\n### JSON файлы\n\n```json\n{\n    \"welcome\": \"Добро пожаловать!\",\n    \"greeting\": \"Привет, {name}!\",\n    \"items\": {\n        \"one\": \"У вас {count} товар\",\n        \"few\": \"У вас {count} товара\",\n        \"many\": \"У вас {count} товаров\",\n        \"other\": \"У вас {count} товаров\"\n    },\n    \"user\": {\n        \"greeting\": \"С возвращением, {name}!\",\n        \"profile\": {\n            \"title\": \"Профиль пользователя\"\n        }\n    }\n}\n```\n\n### Доступ к вложенным ключам\n\nДоступ к вложенным ключам осуществляется через точечную нотацию:\n\n```php\necho $i18n-\u003et('user.profile.title'); // \"Профиль пользователя\"\n```\n\n## Множественное число\n\nPolyglot предоставляет надежную поддержку множественного числа на основе правил CLDR (Common Locale Data Repository):\n\n```php\n// Файл перевода\nreturn [\n    'items' =\u003e [\n        'one' =\u003e 'У вас {count} товар',\n        'few' =\u003e 'У вас {count} товара',\n        'many' =\u003e 'У вас {count} товаров',\n        'other' =\u003e 'У вас {count} товаров'\n    ],\n    'apples' =\u003e [\n        'one' =\u003e '{count} яблоко',\n        'few' =\u003e '{count} яблока',\n        'many' =\u003e '{count} яблок',\n        'other' =\u003e '{count} яблок'\n    ]\n];\n\n// Использование\necho $i18n-\u003etranslatePlural('items', 1); // \"У вас 1 товар\"\necho $i18n-\u003etranslatePlural('items', 3); // \"У вас 3 товара\"\necho $i18n-\u003etranslatePlural('items', 5); // \"У вас 5 товаров\"\n\n// С параметрами\necho $i18n-\u003etranslatePlural('items', 5, ['color' =\u003e 'красных']); // \"У вас 5 красных товаров\"\n```\n\n## Формат сообщений ICU\n\nPolyglot поддерживает формат сообщений ICU (International Components for Unicode) — мощный стандарт для обработки переводов с переменными, множественным числом и многим другим.\n\n### Подстановка параметров\n\n```php\n// Перевод\n'greeting' =\u003e 'Привет, {name}!'\n\n// Использование\necho $i18n-\u003et('greeting', ['name' =\u003e 'Иван']); // \"Привет, Иван!\"\n```\n\n### Форматирование чисел\n\n```php\n// Перевод\n'price' =\u003e 'Цена: {amount, number, currency}'\n\n// Использование\necho $i18n-\u003et('price', ['amount' =\u003e 1234.56]); // \"Цена: 1 234,56 ₽\" (в ru-RU)\n```\n\n### Форматирование дат\n\n```php\n// Перевод\n'today' =\u003e 'Сегодня {date, date, medium}'\n\n// Использование\necho $i18n-\u003et('today', ['date' =\u003e new DateTime()]); // \"Сегодня 1 янв. 2023 г.\"\n```\n\n### Множественное число\n\n```php\n// Перевод\n'items' =\u003e '{count, plural, one{# товар} few{# товара} many{# товаров} other{# товаров}}'\n\n// Использование\necho $i18n-\u003et('items', ['count' =\u003e 1]); // \"1 товар\"\necho $i18n-\u003et('items', ['count' =\u003e 3]); // \"3 товара\"\necho $i18n-\u003et('items', ['count' =\u003e 5]); // \"5 товаров\"\n```\n\n### Выбор по параметру (Select)\n\n```php\n// Перевод\n'gender' =\u003e '{gender, select, male{Он} female{Она} other{Они}} будет присутствовать.'\n\n// Использование\necho $i18n-\u003et('gender', ['gender' =\u003e 'female']); // \"Она будет присутствовать.\"\n```\n\n### Вложенное форматирование\n\n```php\n// Перевод\n'nested' =\u003e '{gender, select, male{У него {count, plural, one{# яблоко} few{# яблока} many{# яблок} other{# яблок}}} female{У неё {count, plural, one{# яблоко} few{# яблока} many{# яблок} other{# яблок}}} other{У них {count, plural, one{# яблоко} few{# яблока} many{# яблок} other{# яблок}}}}'\n\n// Использование\necho $i18n-\u003et('nested', ['gender' =\u003e 'female', 'count' =\u003e 3]); // \"У неё 3 яблока\"\n```\n\n## Построители сообщений\n\nPolyglot предоставляет набор построителей для программного создания шаблонов сообщений ICU.\n\n### Построитель сообщений ICU\n\n```php\nuse Bermuda\\Polyglot\\Generator\\IcuMessage;\n\n// Создание построителя сообщений для конкретной локали\n$builder = IcuMessage::for('ru');\n\n// Создание простого сообщения с заполнителями\n$message = $builder-\u003emessage('Привет, {name}!');\n\n// Создание сообщения с учетом пола\n$gender = IcuMessage::gender(\n    'gender',\n    'Он будет присутствовать', // male\n    'Она будет присутствовать', // female\n    'Они будут присутствовать' // other\n);\n```\n\n### Построитель множественного числа\n\n```php\nuse Bermuda\\Polyglot\\Generator\\IcuMessage;\n\n// Создание построителя множественного числа для русского языка\n$pluralBuilder = IcuMessage::plural('count', 'ru');\n\n// Добавление вариантов вручную\n$pluralBuilder\n    -\u003ewhen('one', 'У вас # товар')\n    -\u003ewhen('few', 'У вас # товара')\n    -\u003ewhen('many', 'У вас # товаров')\n    -\u003eotherwise('У вас # товаров');\n\n// Получение ICU сообщения\n$icuMessage = $pluralBuilder-\u003ebuild();\n// Результат: \"{count, plural, one{У вас # товар} few{У вас # товара} many{У вас # товаров} other{У вас # товаров}}\"\n\n// Использование withInflections для стандартных форм множественного числа\n$builder = IcuMessage::plural('count', 'ru')\n    -\u003ewithInflections('У вас # товар', [\n        'one' =\u003e '',\n        'few' =\u003e 'а',\n        'many' =\u003e 'ов',\n        'other' =\u003e 'ов'\n    ]);\n\n// Для английского (проще)\n$builder = IcuMessage::plural('count', 'en')\n    -\u003ewithInflections('You have # item', [\n        'one' =\u003e '',\n        'other' =\u003e 's'\n    ]);\n```\n\n### Построитель выбора\n\n```php\nuse Bermuda\\Polyglot\\Generator\\IcuMessage;\n\n// Создание построителя выбора\n$selectBuilder = IcuMessage::select('role');\n\n// Добавление вариантов\n$selectBuilder\n    -\u003ewhen('admin', 'У вас полный доступ')\n    -\u003ewhen('manager', 'У вас ограниченный доступ')\n    -\u003eotherwise('У вас базовый доступ');\n\n// Получение ICU сообщения\n$icuMessage = $selectBuilder-\u003ebuild();\n// Результат: \"{role, select, admin{У вас полный доступ} manager{У вас ограниченный доступ} other{У вас базовый доступ}}\"\n\n// Использование со вложенным множественным числом\n$builder = IcuMessage::select('gender')\n    -\u003ewhen('male', function($b) {\n        return $b-\u003eplural('count', 'ru')\n            -\u003ewhen('one', 'У него # яблоко')\n            -\u003ewhen('few', 'У него # яблока')\n            -\u003ewhen('many', 'У него # яблок')\n            -\u003ewhen('other', 'У него # яблок');\n    })\n    -\u003ewhen('female', function($b) {\n        return $b-\u003eplural('count', 'ru')\n            -\u003ewhen('one', 'У неё # яблоко')\n            -\u003ewhen('few', 'У неё # яблока')\n            -\u003ewhen('many', 'У неё # яблок')\n            -\u003ewhen('other', 'У неё # яблок');\n    });\n```\n\n## Кэширование\n\nPolyglot поддерживает кэширование загруженных переводов для повышения производительности:\n\n```php\nuse Bermuda\\Polyglot\\Cache\\PsrCacheAdapter;\nuse Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter;\n\n// Создание PSR-16 совместимого кэша\n$psr16Cache = new \\Symfony\\Component\\Cache\\Psr16Cache(\n    new FilesystemAdapter()\n);\n\n// Создание адаптера кэша\n$cache = new PsrCacheAdapter($psr16Cache);\n\n// Использование с фабрикой I18n\n$i18n = I18nFactory::create(\n    resourcesPath: '/путь/к/переводам',\n    defaultLocale: 'ru',\n    fallbackLocale: 'en',\n    cache: $cache\n);\n```\n\nТакже включен `InMemoryCache` для простых случаев:\n\n```php\nuse Bermuda\\Polyglot\\Cache\\InMemoryCache;\n\n$cache = new InMemoryCache();\n```\n\n## Определение локали\n\nPolyglot может автоматически определять предпочтительную локаль пользователя:\n\n```php\nuse Bermuda\\Polyglot\\Detector\\HttpAcceptLanguageDetector;\nuse Bermuda\\Polyglot\\Detector\\QueryLocaleDetector;\nuse Bermuda\\Polyglot\\Detector\\PathLocaleDetector;\nuse Bermuda\\Polyglot\\Detector\\LocaleDetectorChain;\n\n// Доступные локали\n$availableLocales = ['ru', 'en', 'de', 'fr'];\n\n// Создание детекторов\n$httpDetector = new HttpAcceptLanguageDetector($availableLocales);\n$queryDetector = new QueryLocaleDetector($availableLocales, 'locale');\n$pathDetector = new PathLocaleDetector($availableLocales);\n\n// Создание цепочки детекторов (проверяются по порядку)\n$detector = new LocaleDetectorChain([\n    $pathDetector,    // Сначала проверяем путь URL (/ru/page)\n    $queryDetector,   // Затем проверяем параметр запроса (?locale=ru)\n    $httpDetector     // Наконец проверяем заголовок Accept-Language\n]);\n\n// Использование с I18n\n$i18n = new I18n($translator, $detector);\n\n// Определение и установка локали\n$i18n-\u003edetectAndSetLocale('ru'); // 'ru' - это локаль по умолчанию, если не удалось определить\n```\n\n## PSR-15 Middleware\n\nPolyglot включает PSR-15 middleware для определения локали из HTTP-запросов:\n\n```php\nuse Bermuda\\Polyglot\\I18nMiddleware;\n\n// Создание middleware\n$middleware = I18nFactory::createMiddleware($i18n, 'ru');\n\n// Добавление в конвейер middleware\n$app-\u003epipe($middleware);\n```\n\nMiddleware:\n1. Определяет локаль из запроса\n2. Устанавливает её в экземпляре I18n\n3. Добавляет локаль как атрибут запроса\n4. Передает управление следующему middleware\n\n## Лицензия\n\nБиблиотека Polyglot распространяется под [лицензией MIT](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbermudaphp%2Fpolyglot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbermudaphp%2Fpolyglot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbermudaphp%2Fpolyglot/lists"}