Str::length
Returns the number of characters in a string, counting multibyte characters as one each.
Str::length(string $value, ?string $encoding = null): intParameters
| Parameter | Type | Description |
|---|---|---|
$$value | string | The string to measure. |
$$encodingoptional | string|null= null | Character encoding to interpret the bytes with. When null, PHP's internal encoding is used, which is UTF-8 by default. |
Return value
intA non-negative count of characters in the string.
Errors
mb_strlen raises a ValueError if $encoding is not a recognised encoding name.
Str::length delegates straight to mb_strlen. The reason to use it instead of strlen is that strlen counts bytes: in UTF-8 an accented letter is two bytes and most emoji are four, so strlen('résumé') reports 8 for a six-character word. Any length you show a user, store as a character limit, or compare against a validation rule should come from this method.
Characters are code points, not what the reader sees
The unit here is the Unicode code point, not the grapheme cluster the user perceives as one character. é written as a single precomposed code point counts as 1, while the same glyph written as e plus a combining acute counts as 2 — identical on screen, different numbers. Emoji built from joined sequences, such as a family or a flag, count once per component. If you need the number of visible glyphs, use grapheme_strlen from the intl extension and normalise the input first.
Encoding
Leave $encoding alone unless you are genuinely handling non-UTF-8 bytes. Passing the wrong encoding does not convert anything — it only changes how the existing bytes are grouped, which silently produces a wrong count.
Example
When to use it
- Enforce a character limit on a bio or SMS body where accented text must not be penalised.
- Show a live 'x of 280 characters' counter that matches what the backend validates.
- Decide whether a value is short enough to display in full or needs Str::limit.
Frequently asked questions
What is the difference between Str::length and strlen?
Str::length counts characters and strlen counts bytes, so they only agree on pure ASCII. For 'résumé' Str::length returns 6 and strlen returns 8, because each accented letter occupies two bytes in UTF-8.
Why does Str::length return 2 for a single accented character?
The character was written in decomposed form — a base letter followed by a combining accent — which is two code points. Normalise the string with Normalizer::normalize($value, Normalizer::FORM_C) before measuring if you want the precomposed count.
Does Laravel's max validation rule use characters or bytes?
Characters, via the same multibyte counting Str::length performs, provided the mbstring extension is loaded. That is why a byte-based counter in your frontend can disagree with the server on accented or emoji input.
More examples
A character counter that agrees with validation
The middle row is the important one: 18 characters but 20 bytes. A strlen-based counter would have rejected a bio that Laravel's max:18 validation rule accepts, because that rule also measures in characters. Note also that str_pad would not have aligned these columns — it pads by bytes, so the multibyte rows come out short.
<?php
use Illuminate\Support\Str;
$limit = 18;
$bios = [
'Plain ASCII bio',
'Café owner, Zürich',
'Ships code 🚀 daily 🚀',
];
foreach ($bios as $bio) {
$used = Str::length($bio);
$fits = $used <= $limit ? 'ok' : 'too long';
echo $bio, ': ', $used, '/', $limit, " ({$fits}), ", strlen($bio), " bytes\n";
}
// Plain ASCII bio: 15/18 (ok), 15 bytes
// Café owner, Zürich: 18/18 (ok), 20 bytes
// Ships code 🚀 daily 🚀: 20/18 (too long), 26 bytesCounting visible glyphs instead of code points
Three different, all correct, answers for the same string. Str::length gives 5 because the joiners between the emoji are themselves code points. Reach for grapheme_strlen when the number has to match what a person would count on screen.
<?php
use Illuminate\Support\Str;
$family = "👨\u{200D}👩\u{200D}👧";
echo strlen($family), "\n";
// 18 — bytes
echo Str::length($family), "\n";
// 5 — code points: three emoji plus two zero-width joiners
echo grapheme_strlen($family), "\n";
// 1 — what a human sees (requires ext-intl)
Discussion