Склонения слов на php

mychatik

Premium
Premium
26.05.15
429
322
mychatik.ru
#1
Гораздо приятнее читать текст, в котором все слова написаны согласно правилам грамматики, а не "2 человек", "3 час" и.т.д.
Я не говорю уже про извращения, типа "гостя(ей)" и "новость(ей)"
Для того, чтобы текст стал приятнее для чтения можно применить функцию склонения слов.

Я выкладываю рабочую функцию из profile_content.php своего чата:
PHP:
<?php
function num2word($num,$words) { $num=$num%100; if ($num>19) { $num=$num%10; } switch ($num) { case 1: { return($words[0]); } case 2: case 3: case 4: { return($words[1]); } default: { return($words[2]); } }
}
$words_1 = array("год", "года", "лет");
$words_2 = array("день", "дня", "дней");
$words_3 = array("час", "часа", "часов");
$words_4 = array("раз", "раза", "раз");
$words_5 = array("человека", "человек", "человек");
$words_6 = array("поинт", "поинта", "поинтов");
$words_7 = array("секунда", "секунды", "секунд");
?>
Параметры вызова: $num - число, $words - массив склонений нужного слова.
Массивов $words - можно писать сколько угодно. Ровно столько, сколько слов вам нужно склонять.
Чтобы было удобнее формировать массивы со склонениями, запомните ряд чисел 1-2-5, а потом мысленно подставляйте их в массив: (один "рубль", два "рубля", пять "рублей") или (одна "новость", две "новости", пять "новостей").

В сокращённой записи, сама функция будет иметь вид:
PHP:
 function num2word($num,$words) {
return ($words[($num=($num=$num%100)>19?($num%10):$num)==1?0 : (($num>1&&$num<=4)?1:2)]); }
Применяется функция таким образом:
PHP:
echo $num_n." ".num2word($num_n,$words_n);
Несколько примеров из profile_content.php:
PHP:
 <tr> <td align="right">С нами уже:</td> <td><font color="#bf0d0d"><b>&nbsp;<?php echo "".$t_days."&nbsp;".num2word($t_days,$words_2)."&nbsp;и&nbsp;".$t_hours.":".$t_minutes.":".$t_seconds."&nbsp;".num2word($t_hours,$words_3).""?></b></font></td> </tr> <tr> <td align="right">Был в BANе:</td> <td><font color="#bf0d0d">&nbsp;<b><?php echo $current_user->kol_ban."&nbsp;".num2word($current_user->kol_ban,$words_4); ?></b></font></td> </tr> <tr> <td align="right"><?php echo $w_quiz_fastest_answer; ?> :</td> <td><font color="#bf0d0d">&nbsp;<b><?php echo $row['fastest']."&nbsp;".num2word($row['fastest'],$words_7); ?></b></font></td> </tr>
Ну и так далее...

См. также Склонения слов на javascript
 
Последнее редактирование:

mychatik

Premium
Premium
26.05.15
429
322
mychatik.ru
#2
Ещё парочка функций склонения слов:
PHP:
function by_count($count, $form1, $form2, $form3)
{ $count = abs($count) % 100; $lcount = $count % 10; if ($count >= 11 && $count <= 19) return($form3); if ($lcount >= 2 && $lcount <= 4) return($form2); if ($lcount == 1) return($form1); return $form3;
}
Используем функцию следующим образом:
PHP:
$count = 7;
echo $count.' '.by_count($count, 'день', 'дня', 'дней');
===================================

Другая подобная функция:
PHP:
function decl($number, $titles) { $cases = array (2, 0, 1, 1, 1, 2); return $titles[ ($number%100>4 && $number%100<20)? 2 : $cases[min($number%10, 5)] ];
}
Я её применил в моде Банка:
PHP:
echo '<tr><td align="right">Доход:</td><td>&nbsp;</td><td><b>'.$pribil.'</b> кред'.decl($pribil, array('','а','ов')).'</td></tr>';
echo '<tr><td align="right">Сумма к снятию:</td><td>&nbsp;</td><td><b>'.$priz.'</b> кред'.decl($priz, array('','а','ов')).'</td></tr>';
Лично мне эти функции не очень нравится, из-за того, что нужно писать массив склонений или окончаний в каждом месте их вызова.
Но может кому-то они пригодятся.
 
Последнее редактирование:

Rain

Администратор
Команда форума
04.09.14
334
281
28
#3
Лично мне эти функции не очень нравится, из-за того, что нужно писать массив склонений или окончаний в каждом месте их вызова.
Так запросто же можно сделать заготовленные массивы, как в первом примере.
 

mychatik

Premium
Premium
26.05.15
429
322
mychatik.ru
#4
Возникла небольшая проблемка при работе этой функции в чате.

Если прописать её на нужной странице отдельно - всё работает.
Но так как эта функция нужна не на одной странице - я решил "запихнуть" её тело куда-то в общие файлы, а на нужных страницах только её использовать.
Первое, что попробовал - это languages/ru.php.
Всё отлично. В профиле и других местах чата склонения работают.

Но оказалось, что почему-то сразу заглючила статистика от Паши и статистика радиосервера.
Выдало ошибку
Fatal error: Cannot redeclare num2word() in ***languages/ru.php on line 526
526 строка - это и есть сама функция
PHP:
function num2word($num,$words) {
Попробовал сменить в функции $num на $num_1 - не помогло...

Общее этих файлов статистики то, что в них подключен подсчёт количества юзеров в чате.
PHP:
include ('../user_count.php');
Больше никаких файлов чата в статистику радио не подключается.
Ну и, соответственно, в них ещё отдельно прописана сама функция автосклонения.
Удаление функции в статистике не помогло. Ошибка осталась.

Если же закинуть функцию в inc_common.php - в чате тоже всё прекрасно работает, но статистика при этом ошибок не выдаёт, а просто не открывается вообще.

Подскажите, куда можно закинуть эту функцию, чтобы она была общей для чата и не глючила?
Или пусть будет так, как есть - прописывать функцию на каждой нужной странице?.
 
Последнее редактирование:

Rain

Администратор
Команда форума
04.09.14
334
281
28
#5
mychatik, в ошибке сказано что функция с таким названием уже есть. Нужно сменить function num2word на function num2words например, но только в тому случае если они действительно встречаются дважды
 

mychatik

Premium
Premium
26.05.15
429
322
mychatik.ru
#6
Нужно сменить function num2word на function num2words например, но только в тому случае если они действительно встречаются дважды
Сменил...
Вроде работает...
Так откуда взялась второй раз эта функция в чате?
Тем более на странице статистики. При тесте - я её удалял оттуда.
 

Rain

Администратор
Команда форума
04.09.14
334
281
28
#7
mychatik, что-то пропустил значит. Вообще, я бы вставил эту функцию в inc_common.php (предварительно убрав ее декларирование в других файлах) и потом просто вызывал в нужных местах.