PHP Multibyte String Handling with mbstring
Standard PHP string functions often fail when processing multi-byte
encodings like UTF-8, leading to corrupted data and inaccurate string
lengths. This article explains how to use the PHP mbstring
(Multibyte String) extension to safely perform operations such as
calculating length, slicing, and searching strings containing non-ASCII
characters.
Why You Need the mbstring Extension
In single-byte encodings (like ISO-8859-1), every character occupies
exactly one byte. Standard PHP string functions like
strlen() and substr() operate on a
byte-by-byte basis.
However, multi-byte encodings like UTF-8 use between one and four
bytes per character. If you use a standard byte-based function on a
UTF-8 string containing emojis or non-Latin characters, the results will
be incorrect. For example, the German word “münchen” contains 7
characters, but standard strlen() will return
8 because the “ü” character occupies two bytes in
UTF-8.
The mbstring extension solves this by analyzing the byte
sequences as actual characters based on a specified character
encoding.
Setting the Encoding
Before performing multi-byte operations, it is best practice to set the internal encoding so you do not have to pass the encoding type to every function.
// Set the default internal encoding to UTF-8
mb_internal_encoding("UTF-8");Common mbstring Functions and Replacements
The mbstring extension provides direct counterparts to
PHP’s standard string functions.
1. Getting String Length:
mb_strlen
Unlike strlen(), which counts bytes,
mb_strlen() counts the actual number of characters.
$string = "münchen";
echo strlen($string); // Outputs: 8 (bytes)
echo mb_strlen($string); // Outputs: 7 (characters)2. Extracting Substrings:
mb_substr
Using substr() on a multi-byte string can cut a
character in half, resulting in an invalid, corrupted character display.
mb_substr() safely extracts the substring based on
character position.
$string = "こんにちは"; // "Hello" in Japanese (5 characters)
echo substr($string, 0, 3); // Outputs corrupted bytes
echo mb_substr($string, 0, 3); // Outputs: こんに (3 characters)3. Finding Character
Position: mb_strpos
mb_strpos() finds the position of the first occurrence
of a substring in a string based on character count, not byte count.
$string = "Café";
echo strpos($string, "é"); // Outputs: 3 (starts at the 3rd byte, counting C=0, a=1, f=2)
echo mb_strpos($string, "é"); // Outputs: 3 (starts at the 3rd character index)4. Changing Case:
mb_strtolower and mb_strtoupper
Standard case conversion functions like strtolower() do
not recognize accented or non-Latin characters. Use
mb_strtolower() and mb_strtoupper() for
accurate case mapping.
$string = "ÉLÉPHANT";
echo strtolower($string); // Outputs: éLéPHANT (fails on accented capitals)
echo mb_strtolower($string); // Outputs: éléphant (correctly converts all characters)Regular Expressions with Multibyte Strings
If you need to perform regular expression matches on multi-byte
strings, use mb_ereg() or standard PCRE functions
(preg_match()) with the u (UTF-8)
modifier.
$string = "ürgert";
// Using PCRE with the 'u' modifier
if (preg_match('/^ü/u', $string)) {
echo "Matches starting with ü";
}