При разработке русскоязычных проектов, ориентированных на обычного пользователя, таких как социальные сети и сервисы, веб-программисты зачастую сталкиваются с задачей склонения имён пользователей, ников, географических названий и пр. Благодаря новому удобному сервису от Яндекс.Нано эта задача стала элементарной и тривиальной. Небольшой скрипт на PHP поможет Вам легко добавить функцию склонения имён собственных на свой сайт.
В дебрях пользовательских проектов Яндекс.Нано затесался скромный, но очень полезный для русскоязычной аудитории проект Склонятор. Авторы характеризуют его так: «Веб-сервис, для разработчиков. Умеет склонять имена, фамилии и иногда даже ники». От себя хотел бы добавить лишь два слова: «превосходный» и «незаменимый», умеет склонять не только фамилии и имена, но и названия географических объектов и некоторые другие слова.
Для быстрой интеграции с Вашим сайтом понадобится всего навсего одна функция, которая позволяет легко получить нужный падеж имени пользователя.
function inflect ( $name ) { // Building Request URL $url = 'http://export.yandex.ru/inflect.xml?name='.urlencode($name); // Processing CURL Request $curl = curl_init( $url ); curl_setopt( $curl, CURLOPT_USERAGENT, 'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.6.30 Version/10.61' ); // Just for fun, or ... curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 ); $result = curl_exec( $curl ); curl_close( $curl ); // Preparing Inflections $cases = array (); preg_match_all( '#\<inflection\s+case\=\"([0-9]+)\"\>(.*?)\<\/inflection\>#si', $result, $m ); // Creating Inflection List if ( count($m[0]) ) { foreach ( $m[1] as $i => &$id ) { $cases[ (int) $id ] = $m[2][$i]; } unset ( $id ); } else return null; // Sending Request Back to User if ( count( $cases ) > 1 ) { return $cases; } else return false; }
Её использование элементарно — при вызове, функция inflect получает единственный параметр — склоняемое имя. Если имя не удалось просклонять (в случае отказа связи или несклоняемого имени) функция возвращает false или null. В случае успеха, функция возвращает массив имён пользователя в зависимости от падежа (с 1 по 6 номер). Результат получается в кодировке UTF-8.
Если немного доработать имеющуюся функцию, можно значительно повысить её быстродействие, добавив элементарное кэширование запросов к серверу. Дополнительно мы создаём константу INFLECT_CACHE, хранящую значение пути к файлам кэша запросов.
define ( 'ABSPATH', dirname(__FILE__).'/' ); define ( 'INFLECT_CACHE', ABSPATH . 'cache/inflect.%s.txt' ); function inflector ( $name ) { // Getting Cachable ID $nid = md5( $name ); // Checking for Cached Version if ( file_exists(sprintf(INFLECT_CACHE, $nid)) ) { // Loading form Cache $cases = file_get_contents( sprintf(INFLECT_CACHE, $nid) ); $cases = unserialize( $cases ); return $cases; } else { // Building Request URL $url = 'http://export.yandex.ru/inflect.xml?name='.urlencode($name); // Processing CURL Request $curl = curl_init( $url ); curl_setopt( $curl, CURLOPT_USERAGENT, 'Opera/9.80 (Windows NT 6.1; U; ru) Presto/2.6.30 Version/10.61' ); // Just for fun, or ... curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 ); $result = curl_exec( $curl ); curl_close( $curl ); // Preparing Inflections $cases = array (); preg_match_all( '#\<inflection\s+case\=\"([0-9]+)\"\>(.*?)\<\/inflection\>#si', $result, $m ); // Creating Inflection List if ( count($m[0]) ) { foreach ( $m[1] as $i => &$id ) { $cases[ (int) $id ] = $m[2][$i]; } unset ( $id ); } else return false; // Saving Result and Sending back to User file_put_contents( sprintf(INFLECT_CACHE, $nid), serialize($cases) ); return $cases; } }
С такой доработкой каждый из запросов будет сохраняться в дисковом кэше и нагрузка на сеть будет минимальной, а соответственно и скорость получения ответов — мгновенной.
Рассмотрим пример работы скрипта с самым простым и привычным именем:
// Request for the Pupkin inflect( 'Василий Иванович Пупкин' ); // The Result of Pupkin's $inflection = array ( 1 => 'Василий Иванович Пупкин', 2 => 'Василия Ивановича Пупкина', 3 => 'Василию Ивановичу Пупкину', 4 => 'Василия Ивановича Пупкина', 5 => 'Василием Ивановичем Пупкиным', 6 => 'Василии Ивановиче Пупкине', );
Как видно из примера, функция сразу же даёт приятный положительный результат и склоняет полное Ф.И.О. без каких-либо проблем. Результат может легко использоваться в сочетании с простой функцией «имя пользователя», которая получает на вход имя и падеж.
function username( $name, $case = 1 ) { $cases = inflect( $name ); if ( $cases && count( $cases ) > 1 ) { return $cases[$case]; } else return $name; }
Применяя в коде username(‘Вася’, 2) мы получим текст «Васе» и не будем более иметь проблем с падежами русских имён собственных, географических названий, ников и прочих слов.