Str::wordCount

Counts the words in a string, optionally treating extra characters as part of a word.

Signature
Str::wordCount(string $string, ?string $characters = null): int
  • Added in Laravel 8.38

Parameters

ParameterTypeDescription
$$stringstringThe string to count words in.
$$charactersoptionalstring|null= nullAdditional characters to treat as part of a word, given as a plain string of characters. Ranges may be written as 'a..z'.

Return value

intThe number of words found, where a word is a run of letters plus any additional characters supplied.

Changelog

  • PHP 9.xThe $characters argument was added, allowing digits and other symbols to be counted as word characters.

Str::wordCount is a direct pass-through to PHP's str_word_count. A word is a run of alphabetic characters; the apostrophe and the hyphen are already included, so don't and well-known each count as one.

Use it for reading-time estimates, word-limit checks on user submissions, and rough content metrics.

The big caveat

It is not multibyte aware. str_word_count works on bytes against the C locale, so any non-ASCII letter acts as a word separator. naïve approach counts as 3, not 2, because naïve is split into na and ve. On French, German, Turkish or any non-Latin text the number is simply wrong. For accurate counts on international content, use preg_split('/\s+/u', ...) on a squished string instead.

Other things to know

  • Digits are not letters, so PHP 8 rocks counts as 2. Pass '0123456789' as the second argument to count numeric tokens.
  • Punctuation and repeated whitespace are ignored, so pre-squishing changes nothing about the count.
  • An empty string returns 0, and a string of only punctuation does too.

Example

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

When to use it

  • Estimate a reading time for an article by dividing the count by a words-per-minute figure.
  • Enforce a word limit on a submitted bio or abstract that a character limit cannot express.
  • Report rough content length in an editorial dashboard.

Frequently asked questions

Why does Str::wordCount return the wrong number for accented text?

Because it wraps str_word_count, which is byte based and treats any non-ASCII byte as a separator, so 'naïve' counts as two words. Split on whitespace with preg_split('/\\s+/u', ...) for international text.

Does Str::wordCount count numbers as words?

Not by default — digits are not alphabetic. Pass the digits as the second argument, as in Str::wordCount('PHP 8 rocks', '0123456789'), to include numeric tokens in the total.

How do I estimate reading time in Laravel?

Divide Str::wordCount by a words-per-minute figure, typically 200, and round up with a minimum of one minute. Squish the text first so that stray whitespace does not affect anything else you derive from it.

More examples

A reading-time estimate

Prints "10 words, 1 min read". The max(1, ...) guard matters because any article under 200 words would otherwise report zero minutes. The two dumps are 2 and 4: without the digit list only "Vol" and "of" are words, and adding the digits brings "3" and "5" into the count.

Example · php
<?php

use Illuminate\Support\Str;

$text = 'Laravel is a web application framework with expressive, elegant syntax.';

$words = Str::wordCount(Str::squish($text));
$minutes = max(1, (int) ceil($words / 200));

echo $words, ' words, ', $minutes, ' min read', PHP_EOL;

// Counting a version string with and without digits.
var_dump(Str::wordCount('Vol. 3 of 5'));
var_dump(Str::wordCount('Vol. 3 of 5', '0123456789'));

A multibyte-safe alternative

Str::wordCount reports 10 for a seven-word French sentence, because é, ï and à each split their word. The squish-and-split helper reports 7. Use the helper whenever the content is not guaranteed to be plain ASCII; it is also cheap enough to register as a Str macro.

Example · php
<?php

use Illuminate\Support\Str;

function unicodeWordCount(string $value): int
{
    $value = Str::squish($value);

    return $value === '' ? 0 : count(preg_split('/\s+/u', $value));
}

$french = "Une idée naïve à propos du café";

var_dump(Str::wordCount($french));
var_dump(unicodeWordCount($french));

Discussion

  • Be the first to comment on this lesson.