@andreyqin

Как склонять слова по падежам в PHP?

Здравствуйте.

В проекте есть фраза "Поиск среди N товаров", где N - любой число. Есть функция, которая склоняет фразу "N товаров", но в контексте всей фразы склонения получаются неправильными. Например, "Поиск среди 102 товара", а хотелось бы иметь на выходе "Поиск среди 102 товаров". Функции используются стандартные, которые легко нагуглить:

private static $plurals = array(
    'goods' => array('товар', 'товара', 'товаров'),
);

private static function pluralType($n)
{
    return ($n % 10 == 1 && $n % 100 != 11 ? 0 : ($n % 10 >= 2 && $n % 10 <= 4 && ($n % 100 < 10 || $n % 100 >= 20) ? 1 : 2));
}

public static function getPlural($key, $count)
{
    return static::$plurals[$key][static::pluralType($count)];
}

echo Поиск среди {{ $count }} {{ Pluralizer::getPlural('goods', $count) }}


В какую сторону мне копать для решения данной задачи?
  • Вопрос задан
  • 6449 просмотров
Решения вопроса 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Все, что заканчивается на 1, кроме 11 - "Поиск среди N товаров".

private static function pluralType($n)
{
    return $n != 11 && $n % 10 == 1 ? 0 : 1;
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 4
65536
@65536
Вот дарю отполированную функцию
function ending($number, $one, $two, $five)
{
    $number = $number % 100;

    if ( ($number > 4 && $number < 21) || $number == 0 )
    {
        $ending = $five;
    }
    else
    {
        $last_digit = substr($number, -1);

        if ( $last_digit > 1 && $last_digit < 5 )
            $ending = $two;
        elseif ( $last_digit == 1 )
            $ending = $one;
        else
            $ending = $five;
    }

    return $ending;
}

На вход даем число, и отвечаем на вопросы один, два, пять. Если это товары, то:
'Товар' . ending($number, '', 'а', 'ов')

Не обязательно окончания, можно и полные слова, а есть случаи когда это необходимо, например
ending($years, 'год', 'года', 'лет')
Ответ написан
Henryh
@Henryh
Веб-программист
Я писал подобную функцию на JS, для "символов" Осталось: 1 символ, 2 символа, 5 символов.
На PHP как и на JS алгоритм очень похож на ваш, брать нужно только остаток от деления.
Думаю стоит немного упростить для восприятия алгоритм, чтобы уже переделать под ваши реалии:

if ($count%10==1) $simv='символ';
else if ($count%10==2 or $count%10==3 or $count%10==4) $count='символа';
else $simv='символов';


Получается для фразы "Поиск среди 102 товара" будет даже проще:

if ($count%10==1) $simv='товара';
else $count='товаров';


А потом уже можно заворачивать эту логику в массив и запускать в класс.
Ответ написан
Комментировать
abacabb
@abacabb
deqada
Ответ написан
Комментировать
fenric
@fenric
https://anatoly.fenric.ru/development/sklonenie-sl...
все проще чем кажется.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы