mb_str_split

Splits a string into an array of characters or fixed-size chunks without breaking multibyte characters.

Signature
mb_str_split(string $string, int $length = 1, ?string $encoding = null): array
  • Added in PHP 7.4.0

Parameters

ParameterTypeDescription
$stringstringThe string to split.
$lengthoptionalint= 1Number of characters per chunk. Must be 1 or greater.
$encodingoptional?string= nullCharacter encoding. Null uses the internal encoding.

Return value

arrayAn array of the chunks. An empty input string yields an empty array.

Errors

Throws a ValueError if length is less than 1, or if encoding is not a valid encoding.

Changelog

  • PHP 8.0.0encoding is nullable now.
  • PHP 8.0.0This function no longer returns false on failure; an invalid length now throws a ValueError instead.

mb_str_split() turns a string into an array whose elements are whole characters, or chunks of length characters. It is the fix for str_split(), which slices by byte and will happily hand you back half of a é — an invalid fragment that breaks json_encode() and prints as a replacement glyph.

When to reach for it

Use it whenever you need per-character access to text that is not guaranteed ASCII: reversing a string, counting character frequencies, shuffling or masking, spelling out an input one glyph at a time, or chunking a message into fixed-size pieces for a protocol that counts characters. It is also the readable way to loop over characters — foreach (mb_str_split($s) as $ch) beats a manual mb_substr() loop, which is O(n²) on long strings.

What trips people up

It splits by codepoint, not by grapheme. A flag emoji, a skin-tone modifier or a base letter followed by a combining accent is several codepoints, so mb_str_split() tears the glyph apart. For user-visible "characters" use grapheme_str_split() from the intl extension instead.

The final chunk is short when the length does not divide evenly, and the array is always a list with sequential integer keys.

Example

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

When to use it

  • Reverse a UTF-8 string safely by splitting, reversing the array and imploding
  • Count how often each character appears in non-ASCII text with array_count_values
  • Break a message into fixed 70-character chunks for an SMS or a fixed-width protocol
  • Mask all but the last four characters of an account identifier

Frequently asked questions

What is the difference between str_split and mb_str_split?

str_split splits by bytes and mb_str_split splits by characters. On any input containing multibyte characters str_split produces invalid fragments, so use mb_str_split for UTF-8 text.

Does mb_str_split handle emoji correctly?

Only for single-codepoint emoji. Emoji with skin tones, flags or zero-width-joiner sequences span several codepoints and get split apart; use grapheme_str_split() from intl if you need whole visible glyphs.

What PHP version added mb_str_split?

PHP 7.4.0. Before 8.0 it returned false on failure; since 8.0 it throws a ValueError for an invalid length or encoding instead.

More examples

Reverse a multibyte string

The first line prints 'eßürG'. The second shows why strrev() is unusable here: it reverses bytes, so the two-byte sequences for ü and ß come out backwards and the output is mojibake.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = 'Grüße';

echo implode('', array_reverse(mb_str_split($s))), "\n";
echo strrev($s), "\n";

Character frequency count

array_count_values works on the character array directly, giving a=2, b=2, c=1, é=1 and four distinct characters. Doing the same with str_split would report the two bytes of é as separate entries and inflate the count to five.

Example · php
<?php
mb_internal_encoding('UTF-8');
$text = 'ababcé';
$counts = array_count_values(mb_str_split($text));
arsort($counts);
print_r($counts);
echo "distinct characters: ", count($counts), "\n";

Discussion

  • Be the first to comment on this lesson.