Рубрики
Backend

Функция склонения чисел на PHP по русски

При работе с мультиязычными сайтами чисел обычно не вызывает проблем

Все правила закладываются в перевод, но иногда возникает необходимость просклонять числа программно.

Далее я приведу пример функции склонения чисел на языке PHP. Пример довольно простой, поэтому не должно возникнуть сложностей переписать его на другом языке при необходимости.

Зачем на сайте чисел?

Данную функцию можно применять к количеству оставленных комментарием, числа товаров, оставшихся секунд и тп.

Теория склонения чисел

Для правильного склонения чисел необходимо всего три формы:

  1. существительное в единственном числе в именительном падеже;
  2. существительное во множественном числе в именительном падеже;
  3. существительное во множественном числе в родительском падеже.

Пример:

  1. деталь;
  2. детали;
  3. деталей.

Если считать от 0 до 9, то при значении от 2 до 4 применяется второй вариант.

При значении равном единице – первый. А при значениях 0 и от 5 до 9 применяется третий вариант.

Также, третий вариант применяется при счете от 10 до 20.

Как реализовать чисел?

Если делить число по модулю 10, то в остатке будет число меньше 10. В числах от 0 до 9 и от 21 производится именно по этому остатку. Поэтому нам просто нужно делить числа по модулю, так мы сможем определить форму склонения.

Условимся, что наша будет принимать два параметра: число и массив с формами склонений.

При запуске функции в цикле такого вида:

$words = [ 'деталь', 'детали', 'деталей' ];
for ( $i = 0; $i <= 32; $i ++ ) {
	echo numberMood( $i, $words ) . PHP_EOL;
}

получим следующий вывод:

0 деталей
1 деталь
2 детали
3 детали
4 детали
5 деталей
6 деталей
7 деталей
8 деталей
9 деталей
10 деталей
11 деталей
12 деталей
13 деталей
14 деталей
15 деталей
16 деталей
17 деталей
18 деталей
19 деталей
20 деталей
21 деталь
22 детали
23 детали
24 детали
25 деталей
26 деталей
27 деталей
28 деталей
29 деталей
30 деталей
31 деталь
32 детали

Это явно показывает, что работает верно.

функции

Листинг функции приведен ниже:

/**
 *  чисел
 * 
 * @param int $value
 * @param array $words - массив состоящий из трех строк.
 * первый элемент: существительное в единственном числе в именительном падеже,
 * второй: существительное во множественном числе в именительном падеже
 * третий: существительное в родительном падеже
 * Пример: ['деталь', 'детали', 'деталей']
 *
 * @return string
 */
function numberMood( int $value, array $words ): string {
	// если число отрицательное, то $sign = true
	$sign = ! ! $value < 0;

	// определяем цифру, стоящую справа
	$number = abs( $value ) % 10;

	// если правая цифра 0 или больше 5 или число в диапазоне 10-20
	if ( 0 == $number || 5 <= $number || ( 20 >= $value && 10 <= $value ) ) {
		$value .= " {$words[2]}";
	} // если это единица
	elseif ( 1 == $number ) {
		$value .= " {$words[0]}";
		// если в диапазоне от 2 до 4 включительно
	} elseif ( 4 >= $number && 2 <= $number ) {
		$value .= " {$words[1]}";
	}

	// возвращаем строку
	return $sign ? '-' : '' . $value;
}

Внимание!

Информация для тех кто использует старые версии (ниже 7). Чтобы работал корректно, вам следует удалить в определении функции указание типов.

Связанные записи