Strings7 min readExamples run on PHP 8.5.10

str_split()

Learn how PHP 8.4 str_split() cuts a string into an array of fixed-size byte chunks, with examples, error behavior and multibyte pitfalls.

Signature

str_split(string $string, int $length = 1): array

Purpose

str_split() converts a string into an array of pieces that all have the same size, except possibly the last one. With no second argument every piece is a single byte. With a length, each piece holds that many bytes. It is useful for grouping digits, walking over a short ASCII string, or breaking a fixed-width record into fields.

Signature

Parameters and defaults

  • $string is the input string. It may be empty.
  • $length is the maximum size of each chunk, measured in bytes. It defaults to 1. It must be at least 1.

Return value and failure cases

The function returns a list array with integer keys starting at 0. Every element is a string of exactly $length bytes, except the final element, which is shorter when the string length is not an exact multiple of $length.

If $length is greater than the length of the string, you get an array with one element: the whole string.

If $length is less than 1, PHP throws a ValueError. Before PHP 8.0 this situation raised a warning and returned false, so old code that checks for false no longer matches how the function behaves. Since PHP 8.2, an empty input string returns an empty array. Earlier versions returned an array holding one empty string.

Example 1: basic chunking

This example splits a word into chunks of two bytes and shows what happens when the chunk size exceeds the string length.

Example
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
echo json_encode(str_split("Hello", 2), $flags), "\n";
echo json_encode(str_split("abc", 10), $flags), "\n";
Output
["He","ll","o"]
["abc"]

The first call yields a short last chunk ("o"). The second call yields a single element because one chunk is already large enough for everything.

Example 2: grouping digits for display

A common use is formatting a long identifier into readable blocks. Split it into groups of four and join the groups with spaces.

Example
<?php
$digits = "4111111111111111";
$groups = str_split($digits, 4);
echo implode(" ", $groups), "\n";
Output
4111 1111 1111 1111

This works well because the input is plain ASCII digits, where one byte is one character.

Example 3: errors, empty input and multibyte text

This example shows the three edge cases you are most likely to meet: an invalid length, an empty string, and a non-ASCII character.

Example
<?php
try {
    str_split("abc", 0);
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
echo json_encode(str_split("")), "\n";
echo count(str_split("é")), "\n";
Output
ValueError
[]
2

The letter é is stored as two bytes in UTF-8, so the default split returns two elements, and neither one is a valid character on its own.

Edge cases

  • Empty string: in PHP 8.2 and later you get []. If your code indexes [0] on the result, handle the empty case first.
  • Uneven division: the last chunk can be shorter. Do not assume every element has the requested length.
  • Length larger than the string: you get one chunk containing the entire string.
  • Multibyte encodings: chunks are cut at byte boundaries and can split a UTF-8 character in the middle. Such fragments are invalid UTF-8, and json_encode() will fail on them unless you handle the error.
  • Keys: the result is always a zero-based list, so implode(), array_map() and foreach work on it directly.

Common mistakes

  1. Using it on human text with accents, emoji or non-Latin scripts. The function counts bytes, not characters. For code points use mb_str_split(). For user-perceived characters, such as an emoji with modifiers, use grapheme_str_split() when the intl extension is available.
  2. Passing a computed length that can reach zero. For example, intdiv(strlen($s), 10) is 0 for short strings and triggers a ValueError. Clamp it with max(1, ...) or validate it before the call.
  3. Checking for false. That was the pre-8.0 failure signal. Now you catch ValueError if the length comes from untrusted input.
  4. Expecting a delimiter-based split. str_split() cuts by size, not by content. To split on a separator use explode(), and to split on a pattern use preg_split().
  5. Expecting a string back. If you want a single string with separators inserted every N bytes, chunk_split() is closer to that need, although the array form is easier to process further.
  • mb_str_split() splits a multibyte string into characters by code point.
  • grapheme_str_split() splits by grapheme cluster.
  • chunk_split() inserts an ending string after every chunk and returns a string.
  • explode() splits by a separator string.
  • preg_split() splits by a regular expression.
  • count_chars() and str_word_count() report information about the characters or words in a string.

Recap

str_split() turns a string into a list of byte chunks, one byte each by default. The last chunk may be shorter, an empty string gives an empty array in PHP 8.2 and later, and a length below 1 throws ValueError. It is safe for ASCII and fixed-width byte data, but it is the wrong tool for general Unicode text.

Tested examples

Basic chunking and oversized length
<?php
$flags = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
echo json_encode(str_split("Hello", 2), $flags), "\n";
echo json_encode(str_split("abc", 10), $flags), "\n";
Output
["He","ll","o"]
["abc"]
Grouping digits for display
<?php
$digits = "4111111111111111";
$groups = str_split($digits, 4);
echo implode(" ", $groups), "\n";
Output
4111 1111 1111 1111
Errors, empty input and multibyte text
<?php
try {
    str_split("abc", 0);
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
echo json_encode(str_split("")), "\n";
echo count(str_split("é")), "\n";
Output
ValueError
[]
2