Str::plural

Converts an English word to its plural form, returning the singular when the count is exactly one.

Signature
Str::plural(string $value, int|array|\Countable $count = 2, bool $prependCount = false): string

Parameters

ParameterTypeDescription
$$valuestringThe singular English word to inflect.
$$countoptionalint|array|Countable= 2How many things there are. Arrays and Countable objects are counted first. A count whose absolute value is 1 returns the singular.
$$prependCountoptionalbool= falsePrefix the result with the count formatted by Number::format, e.g. '1,000 cars'.

Return value

stringThe pluralised word, or the original word when the count is one, with the original capitalisation preserved.

Errors

With prependCount: true, Number::format throws a RuntimeException when the intl extension is not loaded.

Changelog

  • PHP 12.xThe prependCount argument was added; in 11.x and earlier you had to concatenate the count yourself.

Str::plural runs an inflector over the word — English by default — and picks the singular when the count is one, which is the whole reason to use it instead of appending an s. Pass the collection, array or integer you already have and let it decide.

English by default, and never locale-aware

The rules come from doctrine/inflector, which Laravel configures for English out of the box. It is not English-only: the pluralizer also ships french, norwegian-bokmal, portuguese, spanish and turkish, selected with Pluralizer::useLanguage('spanish') in a service provider's boot method. That is a single global setting rather than something that follows the application locale, and switching it means you should define your Eloquent models' table names by hand. Translated interface copy still needs trans_choice() and a pluralisation string in a language file, not this method. Reach for Str::plural for developer-facing output, table names, and UI where you control the vocabulary.

Zero is plural, one is singular

Only an absolute count of exactly 1 returns the singular, so 0 gives "items" and -1 gives "item". That matches English, but it surprises people expecting a zero-specific branch.

Capitalisation is copied, not guessed

The result is matched against the case of the input: an all-lowercase word stays lowercase, an all-uppercase word comes back uppercase, and a capitalised word stays capitalised. Mixed-case input falls through unchanged in case, so iPhone keeps its lowercase i.

A word ending in punctuation is returned untouched, which is why Str::plural('user.') does nothing.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Render '3 comments' or '1 comment' under a post without an inline ternary.
  • Generate a table or route name from a model class in a code generator.
  • Label a dashboard metric where the unit depends on the value.

Frequently asked questions

How do I show '1 comment' instead of '1 comments' in Laravel?

Pass the count as the second argument: Str::plural('comment', $count) returns the singular whenever the absolute count is 1. Add prependCount: true on Laravel 12 to get the formatted number in front of it.

Does Str::plural work for languages other than English?

It is English by default, but not English-only: Laravel's pluralizer also supports french, norwegian-bokmal, portuguese, spanish and turkish. Switch it application-wide with Pluralizer::useLanguage('spanish') in a service provider's boot method — it is a global setting and does not follow the application locale, and if you change it you should define your Eloquent models' table names explicitly. For interface copy that a translator owns, use trans_choice() with a pluralisation string in a language file instead.

Why did Str::plural return my word unchanged?

Either the count was 1, or the word does not end in a letter or digit — 'user.' and 'user!' are returned verbatim. Strip trailing punctuation before inflecting and add it back afterwards.

More examples

Labelling a count in a view

Passing the collection itself avoids calling count() twice and keeps the label in sync with the data. Note that 0 takes the plural form, which is correct English but differs from languages where zero has its own form.

Example · php
<?php

use Illuminate\Support\Str;

$counts = [0, 1, 2, 17];

foreach ($counts as $n) {
    echo $n, ' ', Str::plural('comment', $n), "\n";
}

// 0 comments
// 1 comment
// 2 comments
// 17 comments

// With a collection, pass it straight in.
$comments = collect(['first']);

echo $comments->count(), ' ', Str::plural('comment', $comments), "\n";
// 1 comment

prependCount and its intl requirement

The thousands separator is what you are buying with prependCount, and it is locale-aware via Number::setLocale(). Without ext-intl the first two calls throw a RuntimeException, so the manual form at the bottom is the safer choice in a package.

Example · php
<?php

use Illuminate\Support\Str;

// Added in Laravel 12. Requires the intl extension,
// because the count goes through Number::format().
echo Str::plural('car', 1000, prependCount: true), "\n";
// 1,000 cars

echo Str::plural('car', 1, prependCount: true), "\n";
// 1 car

// The pre-12 equivalent, with no intl dependency:
$count = 1000;
echo number_format($count), ' ', Str::plural('car', $count), "\n";
// 1,000 cars

Where the inflector will not help you

The first case is the common bug report: the inflector refuses any word not ending in a letter or digit and returns it verbatim. The last line shows the correct tool for localised counts — trans_choice, which needs a booted application and a language file.

Example · php
<?php

use Illuminate\Support\Str;

// Trailing punctuation short-circuits the whole method.
echo Str::plural('user.'), "\n";
// user.

// Case is matched, not inferred, so mixed case is left alone.
echo Str::plural('iPhone'), "\n";
// iPhones

// Translated copy is not this method's job:
// resources/lang/es/messages.php
//   'comments' => '{0} Sin comentarios|{1} Un comentario|[2,*] :count comentarios',
echo trans_choice('messages.comments', 5, ['count' => 5]);

Discussion

  • Be the first to comment on this lesson.