PHP String Length: Bytes, Code Points and Graphemes
Published · Updated
For valid UTF-8 text in PHP 8, use strlen($text) for bytes, mb_strlen($text, 'UTF-8') for code points, and grapheme_strlen($text) for grapheme units. Match the function to the receiving system's rule. Replacing a byte count with a grapheme count changes what the limit measures.
Compare the same input in three units
The strlen documentation defines a byte count. With valid UTF-8, mb_strlen with an explicit UTF-8 encoding counts each encoded code point once. The grapheme_strlen function counts grapheme units instead. The table gives expected results for these exact sequences, not measurements from your PHP deployment.
| Input sequence | Bytes | Code points | Graphemes |
|---|---|---|---|
A | 1 | 1 | 1 |
é (U+00E9) | 2 | 1 | 1 |
e + U+0301 | 3 | 2 | 1 |
😀 (U+1F600) | 4 | 1 | 1 |
U+0020 + A + U+0020 | 3 | 3 | 3 |
| Empty string | 0 | 0 | 0 |
The third row contains a base letter followed by a combining acute accent. Unicode text segmentation groups that sequence as one grapheme, while its two code points occupy three UTF-8 bytes. The precomposed accented letter has different counts. Matching counts do not prove that two strings contain the same code-point sequence.
Make the encoding and extensions explicit
If the encoding argument to mb_strlen is omitted or null, PHP uses its internal character encoding. Pass 'UTF-8' when that is the input contract. The table assumes valid UTF-8; it does not define results for malformed input or text in another encoding.
mb_check_encoding($text, 'UTF-8') checks whether the supplied bytes are valid for that encoding. The mbstring extension must be enabled for these multibyte functions. grapheme_strlen belongs to the intl extension. Check the target PHP environment rather than assuming either extension is available. Falling back to strlen would silently switch a code-point or grapheme rule to bytes.
Keep an empty result separate from failure
grapheme_strlen requires valid UTF-8 and can return false or null on failure. An empty string's count is the integer zero. Check whether the result is an integer, as in is_int($count), before treating it as a usable length; a generic falsy check would also catch zero.
Apply the unit named by the limit
Use the byte count for a rule about the bytes of this string, the code-point count for a code-point rule, or the grapheme count for a grapheme rule. A single grapheme can require several bytes, as the combining-mark example shows. These functions do not establish a universal field maximum or guarantee that a serialized request will fit: a later representation is a separate object to measure.
The String Length guide compares counting units across tools. For the composed and decomposed accent distinction, see Unicode normalization and length before changing the stored text.