mb_strcut

Extracts a substring by byte offset and byte length without splitting a multibyte character.

Signature
mb_strcut(string $string, int $start, ?int $length = null, ?string $encoding = null): string
  • Added in PHP 4.0.6

Parameters

ParameterTypeDescription
$stringstringThe string being cut.
$startintStarting byte offset. Negative counts back from the end of the string.
$lengthoptional?int= nullMaximum length in bytes. Null extracts to the end. A negative value stops that many bytes from the end.
$encodingoptional?string= nullCharacter encoding. Null uses the internal encoding.

Return value

stringThe portion of string described by start and length, trimmed back so it never contains a partial character.

Errors

Throws a ValueError if encoding is not a valid encoding. An out-of-range start returns an empty string rather than false.

Changelog

  • PHP 8.4.0Behaviour is more consistent now on invalid UTF-8 and UTF-16 input.
  • PHP 8.0.0encoding is nullable now.

mb_strcut() looks like mb_substr() but its start and length are measured in bytes, not characters. What makes it multibyte-safe is the correction: if a boundary lands in the middle of a character, the cut is pulled back to that character's first byte, so the result is always valid text — just possibly a byte or two shorter than you asked for.

When to reach for it

Reach for it whenever a hard byte budget exists and the text must stay valid. A VARCHAR(255) in a byte-counting column, a protocol header with a fixed byte field, a fixed-size chunk of a file, an API that caps a field at N bytes of UTF-8 — these are all byte limits, and mb_substr() cannot express them. Conversely, if you are trimming text for a human to read, you want mb_substr() or mb_strimwidth(); a byte-based cut produces a length that varies unpredictably with the content.

What trips people up

People assume it is just mb_substr() with a different name and get results a character or two shorter than expected — that shortfall is the safety mechanism working. Also, strlen() on the result may be less than length, so do not use it to build fixed-size records without padding afterwards.

Example

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

When to use it

  • Trim a UTF-8 value to fit a byte-limited database column without storing a broken character
  • Cut a payload into fixed-byte chunks for a protocol that counts octets
  • Truncate a description to the byte cap an external API enforces on a field

Frequently asked questions

What is the difference between mb_strcut and mb_substr?

mb_strcut measures start and length in bytes, mb_substr measures them in characters. Both return valid text, but mb_strcut trims back to a character boundary when a byte offset falls inside a character.

Does mb_strcut ever return a broken character?

No. If a boundary lands inside a multibyte sequence the cut moves back to that character's first byte, so the returned string is always valid for the given encoding — it may simply be shorter than the requested byte count.

How do I truncate a string to fit a VARCHAR(255) column?

If the column limit is in bytes, use mb_strcut($value, 0, 255). If it is in characters, as with MySQL's utf8mb4 VARCHAR, use mb_substr($value, 0, 255) instead.

More examples

Fit a value into a byte-limited column

A 10-byte cut lands exactly on a character boundary and returns 'Grüße au' — 10 bytes, 8 characters. A 9-byte cut would end mid-'a'... no, it ends cleanly one byte earlier at 'Grüße a', showing the byte count coming back at or below the limit but never above it.

Example · php
<?php
mb_internal_encoding('UTF-8');
$note = 'Grüße aus München';

$fit = mb_strcut($note, 0, 10);
echo $fit, "\n";
echo strlen($fit), " bytes / ", mb_strlen($fit), " chars\n";

$fit9 = mb_strcut($note, 0, 9);
echo $fit9, " -> ", strlen($fit9), " bytes\n";

Chunking a string by byte budget

Each chunk asks for 5 bytes but gets 4 or 5 depending on where the two-byte ñ falls. Advancing the offset by strlen($chunk) rather than by 5 is what keeps the loop aligned to real character boundaries.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = 'añoañoañoaño';
$offset = 0;
while ($offset < strlen($s)) {
    $chunk = mb_strcut($s, $offset, 5);
    echo strlen($chunk), " bytes: $chunk\n";
    $offset += strlen($chunk);
}

Discussion

  • Be the first to comment on this lesson.