Склоняем фамилию на PHP
Некоторое время назад, в очередном проекте, задался целью обращение к пользователям ставить в соответствующий падеж. Например, во фразе «Вам пришло письмо от Васи Пупкина», фамилия и имя стоят в Родительном падеже. Это получается красиво, а главное очень удобно. В то же время пользователю безумно приятно видеть, что программа правильно обращается к нему по имени. Задавшись целью, я не стал сломя голову писать все с нуля, а решил сначала поискать наработки других программистов на этом поприще. Поиски увенчались переменным успехом.
Результаты поисков
Сразу же нашлись несколько скриптов для склонения английских фамилий. Их я немедленно отбросил, поскольку мне нужно было склонение русских фамилий. За ними нашел библиотеки для 1С, Delphi и FoxPro. Но, в конце концов, и мне сопутствовала удача. Нашел одну относительно неплохую библиотеку на php. Скачать ее можно здесь.
Последней интересной находкой по этой теме, были отличыные сервисы Морфер.ру и Яндекс.Склонятор, но об этом ниже.
Найденная библиотека
Найденная библиотека в комментариях не поведала мне о своем наименовании. Архив называется names, но я предлагаю именовать его RussianNameProcessor, по имени основного класса. Сама библиотека срабатывает верно приблизительно в 90-95% случаев, что само по себе достаточно много.
В архиве есть файл для тестирования testNames.php, который объясняет, как работать с библиотекой.
testNames.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?php include ("./names.php"); $a = new RussianNameProcessor( 'Козлов Евгений Павлович'); // годится обычная форма echo "".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor( 'Евгений Павлович Козлов'); // в таком виде тоже echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Козлов', 'Евгений'); // можно явно указать составляющие echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Кунтидия', 'Убиреко', '', 'f'); // можно явно указать пол ('m' или 'f') echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Козлова Евгения Павловна'); echo "<br/>".$a->fullName($a->gcaseRod); ?> |
Соответственно видим следующий текст.
Итак, подключив файл names.php, с помощью include, создаем объект класса RussianNameProcessor. Этот класс является основным и через него идет вся работа. Конструктор объявлен следующим образом:
function RussianNameProcessor (string $lastName, string $firstName = NULL, string $middleName = NULL, string $sex = NULL)
Как видите, в конструктор обязательно нужно передать первый параметр – фамилию. Можно также первым параметром передать строку с фамилией, именем и отчеством, как показано в примере выше.
Следующие параметры можно передать в конструктор:
- string $lastName – фамилия. Может быть указана строка с фамилией, именем и отчеством;
- string $firstName – имя. По умолчанию равно NULL;
- string $middleName – отчество. По умолчанию равно NULL;
- string $sex – пол. Может принимать значение «m» что значит мужской пол или «f» что значит женский пол. По умолчанию равно NULL.
Для работы со склонением фамилий в принципе достаточно одной функции.
string fullName( string $gcase)
Метод в качестве параметра получает название падежа, а возвращает фамилию, имя и отчество в указанном падеже. Падежи записаны в специальных публичных свойствах в классе RussianNameProcessor
- $RussianNameProcessor->gcaseIm или $RussianNameProcessor->gcaseNom – именительный падеж;
- $RussianNameProcessor->gcaseRod или $RussianNameProcessor->gcaseGen – родительный падеж;
- $RussianNameProcessor->gcaseDat – дательный падеж;
- $RussianNameProcessor->gcaseVin или $RussianNameProcessor->gcaseAcc – винительный падеж;
- $RussianNameProcessor->gcaseTvor или $RussianNameProcessor->gcaseIns – творительный падеж;
- $RussianNameProcessor->gcasePred или $RussianNameProcessor->gcasePos – предложный падеж.
Есть также несколько функций для склонения отдельных составляющих:
- string lastName(string $gcase) – метод склоняет отдельно фамилию;
- string firstName(string $gcase) – метод склоняет отдельно имя;
- string middleName(string $gcase) – метод склоняет отдельно отчество.
В эти методы падеж передается точно также как и в метод fullName, т.е. с помощью указанных выше свойств класса RussianNameProcessor.
Хочу отдельно заметить, что эта библиотека настроена так, что хорошо склоняет русские фамилии, записанные в кодировке windows-1251.
Для того чтобы склонять фамилии, записанные в UTF-8, нужно сделать некоторые преобразования.
Во-первых, нужно перекодировать файл names.php в кодировку UTF-8. Сделать это можно в любом нормальном редакторе, рекомендую Notepad++, который можно скачать где угодно, да хотя бы здесь.
Во-вторых, нужно в php настроить перегрузку строковых функций, функциями из расширения mb_string (не забудьте его сначала активировать). Для этого в php.ini напишите mbstring.func_overload = 7.
Теперь можно склонять фамилии, записанные в UTF-8. Для примера можно немного переделать файл testNames.php, перекодировав его в UTF-8.
testNamesUTF.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php header('Content-type:text/html;charset=UTF-8'); //внутреннюю кодировку поставим в утф mb_internal_encoding("UTF-8"); include ("./names.php"); $a = new RussianNameProcessor( 'Козлов Евгений Павлович'); // годится обычная форма echo "".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor( 'Евгений Павлович Козлов'); // в таком виде тоже echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Козлов', 'Евгений'); // можно явно указать составляющие echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Кунтидия', 'Убиреко', '', 'f'); // можно явно указать пол ('m' или 'f') echo "<br/>".$a->fullName($a->gcaseRod); $a = new RussianNameProcessor('Козлова Евгения Павловна'); echo "<br/>".$a->fullName($a->gcaseRod); ?> |
При этом видим ту же картину
Эта библиотека вполне неплохо справляется с поставленной задачей склонения фамилий на русском языке. Поэтому, я считаю, что ее можно использовать в различных проектах.
Морфер.ру
Теперь перейдем к сервисам.
Кого по каким-либо причинам не устаивает вышеописанная библиотека, может использовать специальные сервисы для склонения фамилий и слов. Начнем описание с сервиса morpher.ru.
Этот сервис был разработан и поддерживается программистом Сергеем Слеповым. Разработанная технология отличная и умеет многое:
- склонять слова на русском;
- склонять слова на украинском;
- писать сумму прописью;
- склонять слова в единственном и множественном числе;
- и многое другое.
Сервис представляет собой следующую структуру: обратившись к определенному URL, передав через get или post слово, которое нужно просклонять, получим XML-файл с результатом.
Для примера, я написал небольшой класс для работы с этим сервисом по протоколу HTTP (ещё этот сервис поддерживает SOAP). Скачать этот класс можно отсюда.
Вот небольшой пример работы с этим классом
testMorpher.php
1 2 3 4 5 6 7 8 9 10 11 | <?php //подключаем класс include_once 'morpher.php'; //отправляем заголовки header('Content-type:text/plain;charset=UTF-8'); //создаем объект класса $m = new Morpher(mb_convert_encoding( 'Вася Пупкин','UTF-8','windows-1251')); //получаем склонение var_dump($m->getInflect()); ?> |
В конструктор класса передается слово, которое нужно просклонять, в кодировке UTF-8.
Для того чтобы получить склонение, нужно вызвать метод getInflect(). Этот метод вернет массив со словами в соответствующих падежах либо false, если произошла ошибка.
Сервис позволяет делать не более 100 одинаковых запросов в сутки и не более 1000 запросов в сутки всего. Правда существуют платные варианты, в которых нет данных ограничений.
Яндекс.Склонятор
У Яндекса есть специальная площадка для того, чтобы сотрудники компании могли размещать свои проекты в сети. Эта площадка называется Яндекс.Нано. Среди всех проектов, расположенных на Яндекс.Нано, есть один, который предназначен для склонения фамилий. Он имеет название Яндекс.Склонятор.
Этот сервис чуть-чуть похуже, чем предыдущий. Верность склонения составляет приблизительно 90% (например, мою фамилию неверно поставил в винительный падеж).
Работает этот сервис приблизительно по такой же схеме, что и предыдущий. Единственное отличие Яндекс.Склонятора в том, что он может возвращать данные не только в xml-формате, но еще и в формате json.
Вот небольшой класс, который я написал, чтобы продемонстрировать работу с сервисом.
testYandex.php
1 2 3 4 5 6 7 8 9 10 11 | <?php //отсылаем заголовки header('Content-type:text/plain;charset=UTF-8'); //подключаем класс include_once 'yandex_inflect.php'; //создаем объект $y = new YandexInflect(mb_convert_encoding( 'Вася Пупкин','UTF-8','windows-1251'),'json'); //получаем склонение var_dump($y->getInflect()); ?> |
В конструктор класса передаем слово, которое нужно просклонять в UTF-8, а также наименование формата, в котором будем запрашивать данные у Яндекса: xml или json. По умолчанию установлено в xml.
Метод getInflect() вернет массив со словами в падежах.
Про ограничения этого сервиса ничего не сказано, но я уверен, что такой сервис без ограничений в количестве запросов не обойдется.
Популярность: 12%
Интересное из других блогов:
2leep.comИ не забывайте комментировать статью.
Добавляйся в группу во вконтакте, чтобы самым первым узнавать все новости сайта


Автор: sl4mmer, 30 апреля 2011 в 15:23
используетCgfcb,j pf материал – сэкономил время, думал уж придется самому писать
Автор: sl4mmer, 30 апреля 2011 в 15:24
использует*спасибо за
Автор: Олег, 12 сентября 2011 в 17:22
используетСпасибо автору за статью. Давно такую искал