Signature
mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): stringPurpose
mb_ltrim() removes characters from the beginning of a string and leaves the rest untouched. It is the multibyte-aware counterpart of ltrim(). The older function works on bytes, so it cannot recognise a character such as the ideographic space (U+3000) or an arrow symbol. mb_ltrim() reads the input as characters in a given encoding, so these can be stripped safely. The function is available as of PHP 8.4.
Signature
Parameters and defaults
$stringis the input text.$charactersis optional and defaults tonull. Withnull, the function strips a built-in set of whitespace characters. That set includes the ASCII space, tab, line feed, carriage return, NUL byte, vertical tab and form feed. It also includes Unicode spaces such as the no-break space (U+00A0), the en and em spaces (U+2000 to U+200A), the line and paragraph separators (U+2028, U+2029), the ideographic space (U+3000), NEL (U+0085) and the Mongolian vowel separator (U+180E).- If you pass a string, it is a list of characters to strip. Each character is considered individually, and the order of the list does not matter.
$encodingis optional and defaults tonull. When omitted ornull, PHP uses the current internal encoding, which is UTF-8 unless your configuration says otherwise. Pass a name such as'UTF-8'to make the call independent of that setting.
Return value and failures
The function always returns a string. If nothing at the start matches, you get the original text back. If every character matches, you get an empty string. An encoding name that PHP does not recognise is rejected with an error, so pass only supported names. Passing a custom $characters list replaces the default whitespace set rather than adding to it.
Example 1: Unicode whitespace that ltrim() misses
The string below starts with an ideographic space, a no-break space and two ordinary spaces. The multibyte function removes all four. The byte-based ltrim() stops at the first byte, which is not an ASCII space, so the string keeps its full 12-byte length.
$text = "\u{3000}\u{00A0} Hello";
$trimmed = mb_ltrim($text);
echo json_encode([
'mb' => $trimmed,
'mbLength' => mb_strlen($trimmed),
'ltrimLength' => strlen(ltrim($text)),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"mb":"Hello","mbLength":5,"ltrimLength":12}
Example 2: A custom character list
When you supply $characters, only those characters are removed. The default whitespace is no longer included, so add a space to the list if you want it stripped too.
$label = "\u{2192}\u{2192} Menu";
echo json_encode([
'onlyArrows' => mb_ltrim($label, "\u{2192}"),
'arrowsAndSpace' => mb_ltrim($label, "\u{2192} "),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"onlyArrows":" Menu","arrowsAndSpace":"Menu"}
Example 3: Only the start is changed
Trailing whitespace is preserved. Use mb_rtrim() or mb_trim() when you need the end handled as well. Passing null for $characters keeps the default set while still letting you name the encoding.
$value = " \u{00E9}t\u{00E9} ";
echo json_encode([
'trailingKept' => mb_ltrim($value, null, 'UTF-8'),
'allWhitespace' => mb_ltrim("\u{2003}\u{2003}"),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"trailingKept":"été ","allWhitespace":""}
Edge cases
- An empty input string returns an empty string.
- A string made only of strippable characters becomes
''. - Characters in the middle of the text are never touched, even if they appear in the list.
- Passing an empty string as
$charactersmeans there is nothing to strip, so the input comes back unchanged. Do not confuse this withnull, which selects the default whitespace set. - The input must be valid in the chosen encoding. Text in a different encoding from the one you declare can give unexpected results, so keep the declared encoding and the real data consistent.
Common mistakes
- Treating
$charactersas a prefix.mb_ltrim('abcabcX', 'abc')does not remove oneabc. It removes every leading character that isa,borc, and stops atX. - Expecting default whitespace to survive a custom list. Once you pass your own list, spaces are kept unless you include them.
- Using
ltrim()for Unicode text. Byte-oriented trimming will not remove spaces such as U+3000 or U+2003 unless you list their raw bytes, and doing so risks cutting into a multibyte sequence. - Expecting both ends to be trimmed. The function only affects the start of the string.
- Relying on a server-wide internal encoding. If your code must behave identically everywhere, pass the encoding explicitly.
- Using it on PHP versions before 8.4. The function does not exist there, so guard it with
function_exists()or require PHP 8.4 or later.
Related functions
mb_trim()strips from both ends.mb_rtrim()strips from the end only.ltrim()is the byte-based version for the start of a string.
Recap
Use mb_ltrim() to remove leading whitespace or a chosen set of characters from text that may contain multibyte characters. The default set covers many Unicode spaces. A custom list replaces that default and is treated as a set of individual characters. The return value is always a string.
Tested examples
$text = "\u{3000}\u{00A0} Hello";
$trimmed = mb_ltrim($text);
echo json_encode([
'mb' => $trimmed,
'mbLength' => mb_strlen($trimmed),
'ltrimLength' => strlen(ltrim($text)),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"mb":"Hello","mbLength":5,"ltrimLength":12}
$label = "\u{2192}\u{2192} Menu";
echo json_encode([
'onlyArrows' => mb_ltrim($label, "\u{2192}"),
'arrowsAndSpace' => mb_ltrim($label, "\u{2192} "),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"onlyArrows":" Menu","arrowsAndSpace":"Menu"}
$value = " \u{00E9}t\u{00E9} ";
echo json_encode([
'trailingKept' => mb_ltrim($value, null, 'UTF-8'),
'allWhitespace' => mb_ltrim("\u{2003}\u{2003}"),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"trailingKept":"été ","allWhitespace":""}