cloud-castle / inflector
Многоязычный инфлектор для PHP 8.1+: множественное/единственное число, преобразования регистра, порядковые числительные, slugify с транслитерацией, склонение по падежам и грамматика нескольких языков. Нулевые внешние зависимости.
Requires
- php: >=8.1
- ext-mbstring: *
- cloud-castle/dictionary: >=1.0
Requires (Dev)
- deptrac/deptrac: ^3.0 || ^4.0
- doctrine/inflector: ^2.0
- ergebnis/composer-normalize: ^2.45
- friendsofphp/php-cs-fixer: ^3.75
- icanboogie/inflector: ^2.2
- icanhazstring/composer-unused: ^0.9
- illuminate/support: ^10.0
- infection/infection: ^0.29 || ^0.33
- php-parallel-lint/php-parallel-lint: ^1.4
- phpmd/phpmd: ^2.15
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^1.12 || ^2.1
- phpstan/phpstan-deprecation-rules: ^1.2 || ^2.0
- phpstan/phpstan-phpunit: ^1.4 || ^2.0
- phpstan/phpstan-strict-rules: ^1.6 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.5
- psalm/plugin-phpunit: ^0.19 || ^0.20
- rector/rector: ^1.2 || ^2.0
- roave/security-advisories: dev-latest
- squizlabs/php_codesniffer: ^3.12 || ^4.0
- symfony/string: ^6.4 || ^7.0
- vimeo/psalm: ^6.0
- webmozart/assert: ^1.11
README
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano
CloudCastle Inflector
Многоязычный морфологический инфлектор для PHP 8.1+ с нулевыми внешними зависимостями. Работает с восемью языками (русский, английский, немецкий, французский, испанский, польский, болгарский, румынский): образование множественного/единственного числа, склонение по 6 падежам, спряжение глаголов, согласование с числительными, определение рода и языка, склонение имён и фамилий, числа прописью и обратно (целые и дроби) и обратимая транслитерация латиница↔кириллица.
Установка
composer require cloud-castle/inflector
Требуется PHP 8.1+.
Быстрый старт
<?php
use CloudCastle\Inflector\Inflector;
use CloudCastle\Inflector\Language;
use CloudCastle\Inflector\GrammaticalCase;
$en = new Inflector(Language::English);
echo $en->pluralize('category'); // «categories»
echo $en->singularize('mice'); // «mouse»
$ru = new Inflector(Language::Russian);
echo $ru->decline('город', GrammaticalCase::Genitive); // «города»
echo $ru->pluralizeByCount('город', 5); // «городов» (согласование с числом)
// Транслитерация в обе стороны.
echo $ru->toLatin('Москва'); // «Moskva»
echo $ru->toCyrillic('Moskva'); // «Москва»
// Числа прописью и обратно (все 8 языков, целые со знаком и десятичные дроби).
echo $ru->numberToWords(125); // «сто двадцать пять»
echo $ru->numberToWords(378.56); // «триста семьдесят восемь целых пятьдесят шесть сотых»
echo $ru->wordsToNumber('тысяча двадцать'); // 1020
Возможности
- 8 языков: русский, английский, немецкий, французский, испанский, польский, болгарский, румынский.
- Множественное число / единственное (
pluralize/singularize). - Склонение по 6 падежам (
decline) и склонение имён/фамилий. - Спряжение глаголов по временам (
conjugate). - Согласование с числительными (
pluralizeByCount): 1 город / 2 города / 5 городов. - Правила формы множественного числа (
PluralRules): по локали и количеству — индекс формы для строк видаодин|несколько|многои CLDR-категория (PluralCategory: one/few/many/other). Единый источник правды для инфлексии и внешних потребителей (например, переводчика сообщений). - Числа прописью и обратно (
numberToWords/wordsToNumber): целые со знаком и десятичные дроби на всех 8 языках, с учётом рода и падежей (русский), немецкого словослияния, французской вигезимальной системы, испанских стяжений и множественных форм масштабов (польский/болгарский/румынский). Отдельный публичныйNumberConverter. - Определение рода слова и имени, определение языка текста.
- Транслитерация латиница↔кириллица в обе стороны (обратимо).
- Форматирование дат (
formatDate/formatDateTime) на всех 8 языках: локальный порядок и падеж месяца — «5 марта 2024 года», «5. März 2024», «5 de marzo de 2024».
Примеры по возможностям
Множественное и единственное число
$en = new Inflector(Language::English);
$en->pluralize('analysis'); // «analyses»
$en->pluralize('child'); // «children»
$en->singularize('geese'); // «goose»
$ru = new Inflector(Language::Russian);
$ru->pluralize('стол'); // «столы»
$ru->singularize('окна'); // «окно»
Склонение по падежам и согласование с числом
use CloudCastle\Inflector\GrammaticalCase;
$ru = new Inflector(Language::Russian);
$ru->decline('книга', GrammaticalCase::Dative); // «книге»
$ru->decline('Москва', GrammaticalCase::Prepositional); // «Москве»
// Беглая гласная: словарь для непредсказуемых, эвристика для продуктивного «-ец».
$ru->decline('отец', GrammaticalCase::Genitive); // «отца» (не «отеца»)
$ru->decline('угол', GrammaticalCase::Genitive); // «угла»
$ru->decline('любовь', GrammaticalCase::Genitive); // «любви»
// Согласование существительного с количеством.
$ru->pluralizeByCount('город', 1); // «город»
$ru->pluralizeByCount('город', 3); // «города»
$ru->pluralizeByCount('город', 12); // «городов»
Спряжение глаголов
use CloudCastle\Inflector\Tense;
use CloudCastle\Inflector\Person;
use CloudCastle\Inflector\GrammaticalNumber;
$ru = new Inflector(Language::Russian);
$ru->conjugate('идти', Tense::Past, Person::Third, GrammaticalNumber::Singular); // «шёл»
Правила множественного числа (CLDR)
use CloudCastle\Inflector\PluralRules;
use CloudCastle\Inflector\PluralCategory;
PluralRules::index('ru', 5); // 2 — форма «много» (пять рублей)
PluralRules::category('ru', 2); // PluralCategory::Few
PluralRules::category('en', 1); // PluralCategory::One
Единый источник правды: тот же PluralRules используют и pluralizeByCount,
и внешние потребители — например, cloud-castle/translator.
Числа прописью и обратно (8 языков)
$ru = new Inflector(Language::Russian);
$ru->numberToWords(2024); // «две тысячи двадцать четыре»
$ru->numberToWords(-5); // «минус пять»
$ru->wordsToNumber('сто двадцать пять'); // 125
$de = new Inflector(Language::German);
$de->numberToWords(125); // «einhundertfünfundzwanzig»
$fr = new Inflector(Language::French);
$fr->numberToWords(99); // «quatre-vingt-dix-neuf»
Форматирование дат (8 языков)
use CloudCastle\Inflector\GrammaticalCase;
$ru = new Inflector(Language::Russian);
$ru->formatDate(5, 3, 2024); // «5 марта 2024 года»
$ru->formatDate(8, 3, null, GrammaticalCase::Dative); // «8 марту»
$ru->formatDateTime(new DateTimeImmutable('2024-12-31')); // «31 декабря 2024 года»
(new Inflector(Language::German))->formatDate(5, 3, 2024); // «5. März 2024»
(new Inflector(Language::Spanish))->formatDate(5, 3, 2024); // «5 de marzo de 2024»
(new Inflector(Language::Polish))->formatDate(5, 3, 2024); // «5 marca 2024»
(new Inflector(Language::French))->formatDate(1, 1, 2024); // «1er janvier 2024»
Определение рода, языка и транслитерация
$ru = new Inflector(Language::Russian);
// Род существительного: словарь, затем эвристика по окончанию.
$ru->gender('стол'); // Gender::Masculine
$ru->gender('книга'); // Gender::Feminine
$ru->gender('окно'); // Gender::Neuter
$ru->gender('рубль'); // Gender::Masculine (муж. на «-ь»)
// Пол по личному имени (в любой словоформе).
$ru->genderOfName('Мария'); // Gender::Feminine
$ru->genderOfName('Алексей'); // Gender::Masculine
// Определение языка текста (в авто-режиме, без фиксации языка).
(new Inflector())->detectLanguage('Привет'); // Language::Russian
$ru->toLatin('Щёлково'); // «Shchyolkovo»
$ru->toCyrillic('Shchyolkovo'); // «Щёлково»
Сравнение с аналогами
Все таблицы ниже сгенерированы автоматически из честных сравнительных
тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для всех аналогов,
PHP 8.1.34, без Xdebug.
1. Функциональность
| Возможность | 🏆 CloudCastle | doctrine | symfony | icanboogie | illuminate | наивно¹ |
|---|---|---|---|---|---|---|
| Число: pluralize + singularize | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Регистр: camelize/classify/tableize/underscore | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Порядковые числительные (ordinalize) | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ |
| Slugify с транслитерацией (Unicode → ASCII) | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| Многоязычность с грамматическими падежами | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Склонение с беглой гласной (отец → отца) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Форматирование дат с падежом месяца (8 языков) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Всего | 🏆 7 | 2 | 3 | 3 | 4 | 0 |
2. Безопасность и корректность
| Свойство | 🏆 CloudCastle | doctrine | symfony | icanboogie | illuminate | наивно¹ |
|---|---|---|---|---|---|---|
| Правильная форма: phenomenon → phenomena | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| Правильная форма: index → indices | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Правильная форма: matrix → matrices | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Правильная форма: cactus → cacti | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| Правильная форма: criterion → criteria | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| Всего | 🏆 5 | 4 | 3 | 2 | 4 | 0 |
3. Производительность
Образование мн. числа 20 слов, 40 000 раз (минимум из 4).
| Решение | Время (мс) | Итог |
|---|---|---|
| 🏆 doctrine | 69,8 | быстрейшее среди библиотек |
| CloudCastle | 81,7 | аналог |
| наивно¹ | 106,3 | базовый уровень (не библиотека) |
| illuminate | 748,1 | аналог |
| symfony | 1 974,1 | аналог |
| icanboogie | 3 332,3 | аналог |
4. Потребление памяти
Пик памяти на 40 000 операций (изолированный процесс, только целевая библиотека).
| Решение | Пиковая память (KB) | Итог |
|---|---|---|
| 🏆 CloudCastle | 7 036 | легчайшее среди библиотек |
| doctrine | 7 036 | аналог |
| symfony | 7 036 | аналог |
| icanboogie | 7 036 | аналог |
| наивно¹ | 7 036 | базовый уровень (не библиотека) |
| illuminate | 7 487 | аналог |
¹ Базовый уровень (нативные вызовы/примитивы без полноты решения) показан для контекста и не претендует на победу среди библиотек-аналогов.
Таблица «Корректность форм» построена на реальных вызовах: на трудных словах
(phenomenon, index, matrix, cactus, criterion) алгоритмические инфлекторы
расходятся, а cloud-castle/inflector точен благодаря правилам с лексиконом
исключений. Память измеряется в изоляции (только целевая библиотека в процессе),
иначе совместная загрузка аналогов исказила бы замер.
Вывод: CloudCastle Inflector — самый быстрый и один из самых лёгких, при этом функционально богатейший: помимо множественного числа он склоняет по падежам, образует порядковые, делает slugify с транслитерацией и работает с несколькими языками — при нулевых внешних зависимостях.
Плюсы, минусы и когда применять
Сильные стороны:
- Восемь языков в одном пакете с грамматическими падежами, спряжением и числами прописью — то, чего нет у англо-центричных аналогов.
- Нулевые внешние зависимости, PHP 8.1+, строгая типизация, 100 % покрытие и MSI.
- Быстрее и не тяжелее популярных решений на общей операции (см. таблицы выше).
- Корректные формы трудных английских слов за счёт лексикона исключений.
Ограничения (честно):
- Определение рода (
gender()) для русского использует словарь + эвристику по окончанию и покрывает подавляющее большинство слов; редкие исключения на «-ь» (мужской/женский род) разрешаются по встроенному списку, но он не исчерпывающий. Для других языков родовой эвристики нет (возвращаетсяnull). - Морфология польского/болгарского/румынского покрывает частотные правила, но не все нерегулярные случаи (приближения помечены в PHPDoc правил).
- Склонение существительных с беглой гласной (отец → отца, угол → угла, любовь →
любви) идёт по регулярной парадигме без выпадения гласной — беглость не выводится из
окончания и будет покрыта словарём
cloud-castle/dictionary. При этом названия месяцев на «-ь» и разносклоняемые на «-мя» (знамя → знамени) склоняются корректно. - Транслитерация рассчитана на пару латиница↔кириллица, а не на любые письменности.
Когда применять: генерация человекочитаемых подписей и сообщений (счётчики «5 товаров»), склонение имён в письмах/документах, число прописью в платёжных документах, slug-и для URL, мультиязычные интерфейсы. Когда не стоит: если нужна полноценная лемматизация/морфоанализатор научного уровня — возьмите специализированный NLP-инструмент.
Разработка
composer install
composer check # линтеры + статический анализ + тесты
composer fix # автоисправления (Rector, PHP CS Fixer, PHPCBF)
composer ci # полный CI-пайплайн локально
Полный список команд с описаниями: composer run-script --list.
Документация
- Репозиторий: https://gitverse.ru/cloud-castle/inflector
- История изменений: CHANGELOG.md
- Как внести вклад: CONTRIBUTING.md
- Кодекс поведения: CODE_OF_CONDUCT.md
- Политика безопасности: SECURITY.md
Лицензия
MIT © CloudCastle (alex-4-17@yandex.ru)
🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano