Хочу поделиться одной функцией на языке PHP, которой пользуюсь для вывода корректного окончания в существительных после числительного. Например: «3 места», «17 пользователей» и т.д.

Итак вот сам код:

  function smart_ending($number, $forms, $base = '') {
    $rest = $number % 10;
    $number = (int) substr($number, -2, 2);
    if ($rest == 1 && $number != 11) return $base.$forms[0];
    elseif (in_array($rest, array(2, 3, 4)) && !in_array($number, array(12, 13, 14))) return $base.$forms[1];
    else return $base.$forms[2];
  }

Функция принимает на вход от 2 до 3 параметров. Первый параметр ($number) — это число, собственно, само числительное. Второй параметр ($forms) это массив форм существительного. Третий параметр ($base) — неизменяющаяся основа слова, его можно указывать для сокращения записи, если в этом есть необходимость.

Например, результат работы функции в обоих случаях будет идентичен:

  echo smart_ending(17, array('пользователь', 'пользователя', 'пользователей')); //пользователей
  echo smart_ending(17, array('ь', 'я', 'ей'), 'пользовател'); //пользователей

Также иногда может быть, что при склонении существительное полностью меняет свою форму. В таких случаях возможен только один вариант вызова функции — без параметра $base.

  echo smart_ending(21, array('день', 'дня', 'дней')); //день

Как это работает?

Существует три варианта склонения:

  1. Если остаток от деления числительного на 10 равен 1.

    Например это числа: 1, 21, 31 и т.д. Форма существительного для них будет одинакова: «1 день», «21 билет».

    Но, исключение составляет число 11 и заканчивающиеся на 11 числа 111, 211 и т.д. Остаток от деления таких чисел на 10 тоже равен 1, но использовать ту же форму существительного нельзя: «11 день».

    Поэтому в функции этот момент должен учитываться.

  2. Если остаток от деления числительного на 10 равен 2, 3 или 4.

    Например это числа: 2, 23, 34 и т.д. Форма существительного для них будет тоже одинакова: «22 дня», «4 билета».

    Но, опять не обошлось без исключений. Числа 12, 13, 14 и заканчивающиеся на эти цифры числа 114, 212 и т.д. Как и в предыдущем случае, остаток от деления таких чисел на 10 удовлетворяет условию, но форма существительного будет неверна: «14 дня».

    Этот момент тоже должен учитываться в функции.

  3. Все остальные остатки от деления числительного на 10, а также исключения из предыдущих двух вариантов — используют третью форму существительного. Примеры: «12 дней», «18 билетов», «111 часов».

Все эти условия отражены в функции smart_ending, обеспечивая тем самым корректность её работы.

Вот такая простая и, надеюсь, удобная функция получилась.

Рассказать друзьям: