Str::length

Returns the number of characters in a string, counting multibyte characters as one each.

Signature
Str::length(string $value, ?string $encoding = null): int

Parameters

ParameterTypeDescription
$$valuestringThe string to measure.
$$encodingoptionalstring|null= nullCharacter 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

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

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.

Example · php
<?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 bytes

Counting 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.

Example · php
<?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

  • Be the first to comment on this lesson.