Search by

cloud-castle / inflector

alex-4-17

Многоязычный инфлектор для PHP 8.1+: множественное/единственное число, преобразования регистра, порядковые числительные, slugify с транслитерацией, склонение по падежам и грамматика нескольких языков. Единственная зависимость — словарь cloud-castle/dictionary.

v1.7.0 2026-09-08 07:22 UTC

README

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

CloudCastle Inflector

CloudCastle Inflector

Packagist Version PHP Version License Downloads Monthly Packagist Stars Advisories

Quality Docs Release Stars Forks Issues

PHPStan Psalm PHPMD PHPCS Rector Deptrac Coverage Infection MSI OpenSSF Scorecard

Многоязычный морфологический инфлектор для PHP 8.1+ с единственной зависимостью — словарём выверенных словоформ cloud-castle/dictionary. Работает с восемью языками (русский, английский, немецкий, французский, испанский, польский, болгарский, румынский): образование множественного/единственного числа, склонение по 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

Возможности

На каждую возможность есть отдельная страница с диаграммой работы, таблицей сравнения с пятью аналогами и рекомендациями по применению:

СтраницаО чём
Число существительныхмножественное и единственное число, согласование с числительным
Склонение по падежам6 падежей обоих чисел, беглые гласные
Спряжение глаголоввремя, лицо, число, родовые формы прошедшего
Числа прописьючисло словами и обратный разбор, дроби
Форматирование датдаты и календарные названия на 8 языках
Транслитерация и слагиобратимая пара кириллица ↔ латиница, URL-слаги
Преобразования имёнcamelize, underscore, tableize, classify
Определение рода и языкарод слова и имени, язык текста
Пользовательские правиласвои нерегулярные пары и правила-регулярки
Архитектураслои, порядок источников форм, кэши
Сравнение с аналогамиавтогенерируемые таблицы по шести срезам
  • 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».
  • Календарные названия (monthName / weekdayName) — месяцы и дни недели языка напрямую, в любом падеже; нумерация дней по ISO-8601, как формат N у date().

Примеры по возможностям

Множественное и единственное число

$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->monthName(3);                                  // «март»
$ru->monthName(3, GrammaticalCase::Genitive);       // «марта»
$ru->weekdayName(1);                                // «понедельник»
$ru->weekdayName(3, GrammaticalCase::Genitive);     // «среды»

(new Inflector(Language::Polish))->monthName(3);    // «marzec» (в дате — «marca»)
(new Inflector(Language::German))->weekdayName(6);  // «Samstag»

Определение рода, языка и транслитерация

$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');   // «Щёлково»

Справочник API

Все публичные методы фасада Inflector. Подробности и примеры — на страницах возможностей выше.

МетодЧто делает
pluralize(string): stringмножественное число
singularize(string): stringединственное число
pluralizeByCount(string, int): stringформа, согласованная с числом (1 товар / 2 товара / 5 товаров)
decline(string, GrammaticalCase, GrammaticalNumber): stringпадежная форма слова
declineName(string, GrammaticalCase): stringпадежная форма личного имени
conjugate(string, Tense, Person, GrammaticalNumber, ?Gender): stringформа глагола
gender(string): ?Genderграмматический род слова
genderOfName(string): ?Genderграмматический род имени
detectLanguage(string): Languageязык произвольного текста
formatDate(int, int, ?int, GrammaticalCase): stringдата по нормам языка
formatDateTime(DateTimeInterface, GrammaticalCase): stringто же из объекта даты
monthName(int, GrammaticalCase): stringназвание месяца
weekdayName(int, GrammaticalCase): stringназвание дня недели (ISO-8601)
numberToWords(string\|int\|float): stringчисло прописью
wordsToNumber(string): int\|floatобратный разбор в число
ordinalize(int): stringпорядковое числительное целиком (3rd)
ordinal(int): stringтолько суффикс порядкового (rd)
transliterate(string): stringтранслитерация с автовыбором направления
toLatin(string): stringкириллица в латиницу
toCyrillic(string): stringлатиница в кириллицу
slugify(string, string): stringURL-слаг с транслитерацией
camelize(string): stringfoo_bar в fooBar
pascalize(string): stringfoo_bar в FooBar
underscore(string): stringFooBar в foo_bar
dasherize(string): stringfoo_bar в foo-bar
tableize(string): stringкласс в имя таблицы (FooBar в foo_bars)
classify(string): stringимя таблицы в класс (foo_bars в FooBar)
titleize(string): stringfoo_bar в Foo Bar
humanize(string): stringfoo_bar_id в Foo bar
capitalize(string): stringпервая буква заглавной
addIrregular(string, string): selfсвоя нерегулярная пара
addUncountable(string): selfсвоё неисчисляемое слово
addPluralRule(string, string): selfсвоё правило множественного числа
addSingularRule(string, string): selfсвоё правило единственного числа

Методы add* возвращают сам инфлектор — вызовы связываются в цепочку — и сбрасывают кэши, чтобы форма не пережила замену правил.

Сравнение с аналогами

Все таблицы ниже сгенерированы автоматически из честных сравнительных тестов (benchmarks/compare.php) на ОДИНАКОВОЙ операции для всех аналогов, PHP 8.3.32, без Xdebug.

1. Функциональность

Возможность🏆 CloudCastledoctrinesymfonyicanboogiecakephpilluminateнаивно¹
Число: pluralize + singularize
Регистр: camelize/classify/tableize/underscore
Порядковые числительные (ordinalize)
Slugify с транслитерацией (Unicode → ASCII)
Многоязычность с грамматическими падежами
Склонение с беглой гласной (отец → отца)
Форматирование дат с падежом месяца (8 языков)
Всего🏆 7233340

2. Безопасность и корректность

Свойство🏆 CloudCastledoctrinesymfonyicanboogiecakephpilluminateнаивно¹
Правильная форма: phenomenon → phenomena
Правильная форма: index → indices
Правильная форма: matrix → matrices
Правильная форма: cactus → cacti
Правильная форма: criterion → criteria
Всего🏆 5432340

3. Производительность

Образование мн. числа 20 слов, 40 000 раз (минимум из 4).

РешениеВремя (мс)Итог
🏆 CloudCastle161,3быстрейшее среди библиотек
doctrine213,7аналог
cakephp265аналог
наивно¹265базовый уровень (не библиотека)
illuminate1 192,2аналог
symfony5 407,6аналог
icanboogie9 682,1аналог

4. Потребление памяти

Собственный след библиотеки на 40 000 операций (изолированный процесс, дельта к baseline без библиотеки).

РешениеПиковая память (KB)Итог
наивно¹0базовый уровень (не библиотека)
🏆 cakephp6легчайшее среди библиотек
symfony62аналог
icanboogie103аналог
CloudCastle386аналог
doctrine452аналог
illuminate722аналог

5. Утечки памяти

Рост памяти на второй волне из 20 000 новых уникальных слов после такой же первой (0 — библиотека не течёт).

РешениеРост памяти (KB)Итог
🏆 CloudCastle0не течёт (рост 0)
symfony0аналог
icanboogie0аналог
наивно¹0базовый уровень (не библиотека)
doctrine2 843аналог
cakephp2 843аналог
illuminate2 843аналог

6. Качество кода

Критерий🏆 CloudCastledoctrinesymfonyicanboogiecakephpilluminateнаивно¹
Строгая типизация во всех файлах (declare(strict_types=1))
Типы возвращаемых значений у всех публичных методов
Требует современный PHP 8.1+
Без сторонних runtime-зависимостей (кроме PSR/ext/cloud-castle)
Не течёт на потоке уникальных слов
Всего🏆 5322111

¹ Базовый уровень (нативные вызовы/примитивы без полноты решения) показан для контекста и не претендует на победу среди библиотек-аналогов.

Таблица «Корректность форм» построена на реальных вызовах: на трудных словах (phenomenon, index, matrix, cactus, criterion) алгоритмические инфлекторы расходятся, а cloud-castle/inflector точен благодаря правилам с лексиконом исключений. Память измеряется как собственный след библиотеки: в изолированном процессе (только целевая библиотека) из результата вычитается baseline — тот же процесс с автозагрузчиком, данными и прогретым циклом, но без единого класса библиотеки. Поэтому в таблице стоит потребление самой библиотеки, а не интерпретатора PHP и харнесса замера. Утечки проверяются двумя волнами по 20 000 новых уникальных слов: библиотека с ограниченным кэшем держит память на месте, с неограниченным — растёт линейно. Признаки качества кода читаются из исходников установленных пакетов, а не из заявлений авторов.

Вывод: CloudCastle Inflector — самый быстрый среди аналогов и функционально богатейший: помимо множественного числа он склоняет по падежам, спрягает глаголы, образует порядковые, делает slugify с транслитерацией и работает с восемью языками — при единственной зависимости (словарь cloud-castle/dictionary).

Плата за это — собственный след памяти (≈390 KB) выше, чем у англо-центричных минималистов: cakephp (6 KB), symfony (86 KB) и icanboogie (103 KB) решают только английское число, тогда как пакет держит в памяти правила и словари восьми языков. Против сопоставимого по охвату illuminate/support (731 KB) он почти вдвое легче. Это осознанный компромисс: функциональностью, скоростью, отсутствием утечек и корректностью мы не жертвуем ради килобайтов.

Плюсы, минусы и когда применять

Сильные стороны:

  • Восемь языков в одном пакете с грамматическими падежами, спряжением и числами прописью — то, чего нет у англо-центричных аналогов.
  • Единственная зависимость (cloud-castle/dictionary — словарь выверенных словоформ той же экосистемы), PHP 8.1+, строгая типизация, 100 % покрытие и MSI.
  • Быстрейший среди аналогов на общей операции — заметно быстрее doctrine, cakephp, illuminate, symfony и icanboogie (см. таблицы выше).
  • Не течёт: кэши ограничены, поэтому на потоке уникальных слов память стоит на месте, тогда как doctrine, cakephp и illuminate растут неограниченно.
  • Корректные формы трудных английских слов за счёт лексикона исключений.

Ограничения (честно):

  • Определение рода (gender()) для русского использует словарь + эвристику по окончанию и покрывает подавляющее большинство слов; редкие исключения на «-ь» (мужской/женский род) разрешаются по встроенному списку, но он не исчерпывающий. Для других языков родовой эвристики нет (возвращается null).
  • Морфология польского/болгарского/румынского покрывает частотные правила, но не все нерегулярные случаи (приближения помечены в PHPDoc правил).
  • Собственный след памяти (≈390 KB) выше, чем у англо-центричных минималистов — cakephp (6 KB), symfony (86 KB), icanboogie (103 KB): пакет держит правила и словари восьми языков. Против сопоставимого по охвату illuminate/support (731 KB) — почти вдвое легче. Компромисс осознанный: функциональностью, скоростью, отсутствием утечек и корректностью ради килобайтов не жертвуем.
  • Склонение существительных с беглой гласной (отец → отца, угол → угла, любовь → любви) опирается на словарь 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.

Документация

Лицензия

MIT © CloudCastle (alex-4-17@yandex.ru)

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano