mb_strimwidth

Truncates a string to a given display width, optionally appending an ellipsis marker.

Signature
mb_strimwidth(string $string, int $start, int $width, string $trim_marker = "", ?string $encoding = null): string
  • Added in PHP 4.0.6

Parameters

ParameterTypeDescription
$stringstringThe string being trimmed.
$startintStart offset in characters; negative counts from the end of the string.
$widthintThe maximum display width of the result, marker included. Passing a negative width is deprecated as of PHP 8.3.0.
$trim_markeroptionalstring= ""Text appended when the string is actually truncated; its own width counts against width.
$encodingoptional?string= nullCharacter encoding. Null uses the internal encoding.

Return value

stringThe truncated string, including trim_marker if truncation actually happened.

Errors

Throws a ValueError if encoding is not a valid encoding; a negative width raises a deprecation notice as of PHP 8.3.0.

Changelog

  • PHP 8.3.0Passing a negative width is deprecated.
  • PHP 8.0.0encoding is nullable now.
  • PHP 7.1.0Support for negative start and width values was added.

mb_strimwidth() is the excerpt function. It cuts a string down to a maximum display width and, unlike a hand-rolled mb_substr() plus '...', it appends the marker only when the string was actually too long, and it counts the marker against the budget so the result never overflows.

Width is not length

Width is mbstring's East Asian width model: ASCII and most Latin characters count as 1, fullwidth and CJK characters count as 2. So mb_strlen('日本') is 2 but mb_strwidth('日本') is 4. That is exactly what you want for terminal columns and monospaced layouts, and it is why this function beats mb_substr() for anything that has to line up.

When to reach for it

Table cells in CLI output, list previews, a fixed-width summary column, log lines capped so they do not wrap. Anywhere the requirement is "no wider than N columns, with a … if it was cut".

What trips people up

The marker's width is subtracted from the budget, so mb_strimwidth($s, 0, 10, '...') keeps at most 7 columns of text. And the default marker is an empty string, so if you forget the fourth argument you get a silent, unmarked truncation. Negative width is deprecated from PHP 8.3.

Example

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

When to use it

  • Show a fixed-width preview of a title in a CLI table without breaking column alignment
  • Build a short excerpt with a trailing ellipsis only when the text was really cut
  • Cap log lines at terminal width so long entries do not wrap

Frequently asked questions

What is the difference between mb_strimwidth and mb_substr?

mb_substr counts characters and always cuts; mb_strimwidth counts display columns, where CJK characters count double, and appends the trim marker only when truncation actually occurred.

Why is my truncated string shorter than the width I asked for?

The trim marker's width is included in the width budget. Passing width 10 with a three-character marker leaves only 7 columns for the text itself.

Does mb_strimwidth add the marker to strings that already fit?

No. If the string is within the requested width it is returned untouched, which is the main advantage over doing mb_substr() and concatenating '...' yourself.

More examples

Width versus character length

The string is 5 characters but 7 display columns wide. mb_strimwidth stops at 5 columns, keeping 日本a; mb_substr keeps all 5 characters and blows the column budget. This is the whole reason to prefer mb_strimwidth for aligned output.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = '日本abc';
echo mb_strlen($s),   " characters\n";
echo mb_strwidth($s), " columns\n";
echo mb_strimwidth($s, 0, 5), "|\n";
echo mb_substr($s, 0, 5), "|\n";

Starting partway in

The first call skips the first three characters and gives 12 columns starting at 'café', with the one-column ellipsis eating the last slot. The second uses a negative start to take the final seven characters, and because they fit inside 20 columns no marker appears.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = 'Le café était très bon';
echo mb_strimwidth($s, 3, 12, '…'), "\n";
echo mb_strimwidth($s, -7, 20), "\n";

Discussion

  • Be the first to comment on this lesson.