chunk_split
Splits a string into fixed-length chunks and inserts a separator after each one.
chunk_split(string $string, int $length = 76, string $separator = "\r\n"): string- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string | string | The string to be chunked. |
$lengthoptional | int= 76 | The chunk length in bytes. |
$separatoroptional | string= \r\n | The line-ending sequence inserted after each chunk. |
Return value
stringThe chunked string, with the separator appended after every chunk including the last one.
Errors
Throws a ValueError if length is less than 1.
chunk_split cuts a string into equal-length pieces and glues them back together with a separator between them. The defaults — 76 bytes and CRLF — come straight from RFC 2045, which is what the function was written for: wrapping base64 MIME bodies for email.
When to reach for it
Use it whenever a format demands fixed-width lines or fixed-size groups: base64 attachment bodies, PEM certificate blocks, hex dumps, or display formatting like grouping a card number into blocks of four.
What trips people up
The separator is appended after every chunk, including the final one, so the result always ends with a separator even when the string divides evenly. Strip it with substr($out, 0, -strlen($sep)) when that trailing newline matters.
It also counts bytes, not characters, and has no idea about word boundaries. On UTF-8 text a chunk can land in the middle of a multi-byte sequence and produce broken glyphs — that is fine for base64 and hex, which are pure ASCII, but wrong for prose. To wrap human-readable text at word boundaries use wordwrap; to get the chunks as an array instead of one glued string use str_split.
Example
When to use it
- Wrap a base64-encoded attachment at 76 characters for a MIME email body.
- Format a long PEM key or certificate into 64-character lines.
- Group a card or IBAN number into readable blocks of four for display.
Frequently asked questions
Why does chunk_split add a separator at the end?
By design — it appends the separator after every chunk, including the last. Remove it with substr($result, 0, -strlen($separator)) or rtrim when the trailing newline is unwanted.
What is the difference between chunk_split and str_split?
str_split returns an array of chunks, while chunk_split returns a single string with the separator inserted between (and after) them. Use str_split when you want to iterate the pieces.
Is chunk_split safe for UTF-8 text?
No. It counts bytes, so a chunk boundary can fall inside a multi-byte character and corrupt it. Use mb_str_split or wordwrap for multi-byte text.
More examples
MIME-style base64 wrapping
With no extra arguments the defaults apply: 76-character lines separated by CRLF. Every line except the last reports exactly 76 characters, which is what RFC 2045 requires for a base64 message body.
<?php
$payload = base64_encode(str_repeat("attachment-bytes;", 12));
echo strlen($payload), " chars on one line\n";
$wrapped = chunk_split($payload);
foreach (explode("\r\n", rtrim($wrapped)) as $i => $line) {
echo $i, ": ", strlen($line), " chars\n";
}Grouping digits for display
The first line shows the trailing separator clearly: the pipe sits one space too far right. rtrim removes it. The IBAN example does not divide evenly, so the final group is shorter — chunk_split never pads.
<?php
$card = "4111111111111111";
echo chunk_split($card, 4, " "), "|end\n";
echo rtrim(chunk_split($card, 4, " ")), "|end\n";
echo chunk_split("GB29NWBK60161331926819", 4, " "), "\n";Bytes, not characters
The chunk boundary at byte 3 falls inside the two-byte sequence for ï, so the separator splits a character and the output prints replacement glyphs. wordwrap on the same string breaks at spaces and leaves the characters intact.
<?php
$text = "na\u{00EF}ve caf\u{00E9}";
echo strlen($text), " bytes\n";
echo bin2hex(chunk_split($text, 3, "|")), "\n";
echo chunk_split($text, 3, "|"), "\n";
echo wordwrap($text, 5, "\n", true), "\n";
Discussion