Signature
chunk_split(string $string, int $length = 76, string $separator = "\r\n"): stringPurpose
chunk_split() walks through a string and inserts a separator after every fixed number of characters. The classic use is wrapping base64_encode() output into lines that follow the RFC 2045 style used in email. It is also handy for visually grouping long identifiers, such as card numbers or hexadecimal digests, into readable blocks.
The key thing to remember is that the separator is added after every chunk, including the last one. The function therefore does not work like implode(), which only puts a glue string between items.
Signature
Parameters and defaults
$stringis the input to be chunked.$lengthis the chunk size. The default is76, the line length commonly used for base64 in mail. It must be greater than zero.$separatoris the sequence inserted after each chunk. The default is"\r\n"(carriage return plus line feed). Pass"\n", a space, a dash or any other string if you need something different.
Return value and failure cases
The function returns a new string; the original is not modified. A string shorter than $length is not left untouched: it comes back with one separator appended. The same applies to an empty string, which is shorter than any positive length.
If $length is zero or negative, PHP 8 throws a ValueError. There is no false return to check. Because the arguments are typed, passing a non-numeric value for $length raises a TypeError in the normal way.
Example 1: the trailing separator
The first example shows both a string that does not divide evenly and one that does. In each case the separator also ends the result.
echo json_encode([
chunk_split('abcdefgh', 3, '-'),
chunk_split('abcdef', 3, '-'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;["abc-def-gh-","abc-def-"]
The eight-letter string yields abc-def-gh-, with the short final chunk followed by a separator. The six-letter string yields abc-def-.
Example 2: wrapping base64 output
This is the use the function was designed for. Encoding first and chunking second keeps every line within a predictable width. Here json_encode() is used only so the newline characters are visible in the output.
$encoded = base64_encode('Hello, World!');
echo json_encode(chunk_split($encoded, 8, "\n"), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;"SGVsbG8s\nIFdvcmxk\nIQ==\n"
The encoded text is SGVsbG8sIFdvcmxkIQ==, which is twenty characters long. It is cut into lines of eight, eight and four characters, and each line ends with a newline.
Example 3: grouping digits for display
Because of the trailing separator, display formatting usually needs one extra step. Removing the final space with rtrim() gives a clean result.
$card = '4111111111111111';
echo rtrim(chunk_split($card, 4, ' ')), PHP_EOL;4111 1111 1111 1111
The sixteen digits become four groups of four, separated by single spaces, with no trailing space left over.
Edge cases
- Exact multiples. A string whose length divides evenly by
$lengthstill ends with the separator. There is no special case that skips it. - Short input. If the string is no longer than the chunk length, you get the original text plus one separator.
- Bytes, not characters. The function counts bytes. For ASCII text, bytes and characters are the same thing, but a multibyte UTF-8 character can be cut in the middle. Splitting a two-byte letter with a length of
1produces two invalid fragments. For text in a multibyte encoding, use a multibyte-aware approach such asmb_str_split()and join the pieces yourself. - Empty separator. An empty separator is allowed, and the output is then identical to the input, so there is little point in doing it.
- Line endings. The default
"\r\n"is correct for email-style data but surprising if you print the result to a Unix terminal or compare it against text that only uses"\n".
Common mistakes
- Forgetting the trailing separator. Code that compares the result with an expected string, or displays it to users, often has an unwanted final dash, space or newline. Trim it when you need only separators between chunks.
- Passing a zero length. Computing the chunk size from user input or a division can yield
0, which throws aValueError. Validate it first. - Expecting an array. The function returns one string. If you want the pieces as separate items,
str_split()is the right tool. - Using it for word wrapping.
chunk_split()cuts at fixed positions regardless of word boundaries. For natural text, usewordwrap(). - Chunking before encoding. Chunk the base64 text, not the raw bytes. Splitting the original data and encoding the pieces separately produces different output.
- Assuming characters in UTF-8. As noted above, the length counts bytes, so accented letters and emoji can be broken.
Related functions
str_split()converts a string into an array of fixed-size pieces.explode()splits a string on a delimiter you supply.wordwrap()wraps text to a line width at word boundaries.base64_encode()produces the text thatchunk_split()is most often used to format.rtrim()removes the trailing separator when you do not want it.
Recap
chunk_split() returns a string in which a separator follows every $length bytes, including the last chunk. Its defaults, 76 and "\r\n", suit base64 for email. Use a positive length, trim the final separator when formatting for display, and prefer str_split() or multibyte-aware code when you need an array or have non-ASCII text.
Tested examples
echo json_encode([
chunk_split('abcdefgh', 3, '-'),
chunk_split('abcdef', 3, '-'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;["abc-def-gh-","abc-def-"]
$encoded = base64_encode('Hello, World!');
echo json_encode(chunk_split($encoded, 8, "\n"), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;"SGVsbG8s\nIFdvcmxk\nIQ==\n"
$card = '4111111111111111';
echo rtrim(chunk_split($card, 4, ' ')), PHP_EOL;4111 1111 1111 1111