Singular or Plural setting to a variable. PHP

10.2k views Asked by At

There are a lot of questions explaining how to echo a singular or plural variable, but none answer my question as to how one sets a variable to contain said singular or plural value.

I would have thought it would work as follows:

$bottom="You have favourited <strong>$count</strong> " . $count == 1 ? 'user':'users';

This however does not work.

Can someone advise how I achieve the above?

11

There are 11 answers

0
anditpainsme On BEST ANSWER

This will solve your issue, thanks to mario and Ternary operator and string concatenation quirk?

$bottom = "You have favourited <strong>$count</strong> " . ($count == 1 ? 'user':'users');
0
Danial Nazari On

In laravel, Str class has plural helper funcion:

use Str;
Str::plural('str');

Or you may use Pluralizer class:

use Illuminate\Support\Pluralizer;
Pluralizer::plural('str')
1
Jesse Kochis On

The best way IMO is to have an array of all your pluralization rules for each language, i.e. array('man'=>'men', 'woman'=>'women'); and write a pluralize() function for each singular word.

You may want to take a look at the CakePHP inflector for some inspiration.

https://github.com/cakephp/cakephp/blob/master/src/Utility/Inflector.php

3
AudioBubble On

You might want to look at the gettext extension. More specifically, it sounds like ngettext() will do what you want: it pluralises words correctly as long as you have a number to count from.

print ngettext('odor', 'odors', 1); // prints "odor"
print ngettext('odor', 'odors', 4); // prints "odors"
print ngettext('%d cat', '%d cats', 4); // prints "4 cats"

You can also make it handle translated plural forms correctly, which is its main purpose, though it's quite a lot of extra work to do.

0
Baba On

You can try using $count < 2 because $count can also be 0

$count =1;
$bottom = sprintf("You have favourited <strong>%d %s</strong>", $count, ($count < 2 ? 'user' : 'users'));
print($bottom);

Output

You have favourited 1 user
1
thescientist On

This is one way to do it.

$usersText = $count == 1 ? "user" : "users";
$bottom = "You have favourited <strong>" . $count . "</strong> " , $usersText;
0
deizel. On

For $count = 1:

    "You have favourited <strong>$count</strong> " . $count == 1 ? 'user' : 'users';
=>               "You have favourited <strong>1</strong> 1" == 1 ? 'user' : 'users';
=>                                                        1 == 1 ? 'user' : 'users';
=>                                                          true ? 'user' : 'users';
// output: 'user'

The PHP parser (rightly) assumes everything to the left of the question mark is the condition, unless you change the order of precedence by adding in parenthesis of your own (as stated in other answers).

0
K.Alex On

Custom, transparent and extension-free solution. Not sure about its speed.

/**
 * Custom plural
 */
function splur($n,$t1,$t2,$t3) {
    settype($n,'string');
    $e1=substr($n,-2);
    if($e1>10 && $e1<20) { return $n.' '.$t3; } // "Teen" forms
    $e2=substr($n,-1);
    switch($e2) {
        case '1': return $n.' '.$t1; break;
        case '2': 
        case '3':
        case '4': return $n.' '.$t2; break;
        default:  return $n.' '.$t3; break;
    }
}

Usage in Ukrainian / Russian:

splur(5,'сторінка','сторінки','сторінок') // 5 сторінок
splur(4,'сторінка','сторінки','сторінок') // 4 сторінки
splur(1,'сторінка','сторінки','сторінок') // 1 сторінка
splur(12,'сторінка','сторінки','сторінок') // 12 сторінок

splur(5,'страница','страницы','страниц') // 5 страниц
splur(4,'страница','страницы','страниц') // 4 страницы
splur(1,'страница','страницы','страниц') // 1 страница
splur(12,'страница','страницы','страниц') // 12 страниц
0
Reality On

If you're going to go down the route of writing your own pluralize function then you might find this algorithmic description of pluralisation helpful:

http://www.csse.monash.edu.au/~damian/papers/HTML/Plurals.html

Or the much easier approach would probably be to use one of the ready-made pluralize functions available on the Internet:

http://www.eval.ca/2007/03/03/php-pluralize-method/

1
mpen On

You can try this function I wrote:

/**
 * Pluralizes a word if quantity is not one.
 *
 * @param int $quantity Number of items
 * @param string $singular Singular form of word
 * @param string $plural Plural form of word; function will attempt to deduce plural form from singular if not provided
 * @return string Pluralized word if quantity is not one, otherwise singular
 */
public static function pluralize($quantity, $singular, $plural=null) {
    if($quantity==1 || !strlen($singular)) return $singular;
    if($plural!==null) return $plural;

    $last_letter = strtolower($singular[strlen($singular)-1]);
    switch($last_letter) {
        case 'y':
            return substr($singular,0,-1).'ies';
        case 's':
            return $singular.'es';
        default:
            return $singular.'s';
    }
}

Usage:

pluralize(4, 'cat'); // cats
pluralize(3, 'kitty'); // kitties
pluralize(2, 'octopus', 'octopii'); // octopii
pluralize(1, 'mouse', 'mice'); // mouse

There's obviously a lot of exceptional words that this function will not pluralize correctly, but that's what the $plural argument is for :-)

Take a look at Wikipedia to see just how complicated pluralizing is!

0
Gerry On

Enjoy: https://github.com/ICanBoogie/Inflector

Multilingual inflector that transforms words from singular to plural, underscore to camel case, and more.