mb_check_encoding

Checks whether a string or array contains only byte sequences that are valid in a given encoding.

Signature
mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool
  • Added in PHP 4.4.3

Parameters

ParameterTypeDescription
$valueoptionalarray|string|null= nullThe string, or array of strings, to validate. Arrays are checked recursively, keys included. Passing null or omitting it is deprecated as of PHP 8.1.
$encodingoptional?string= nullThe encoding the value is expected to be in. If omitted or null, the internal encoding is used.

Return value

booltrue when every byte in value forms a legal sequence in encoding, false otherwise.

Errors

Throws a ValueError if encoding is not a name mbstring recognises; passing null or omitting value emits a deprecation notice on PHP 8.1 and later.

Changelog

  • PHP 8.1.0Calling the function with null as value, or with no arguments at all, is deprecated.
  • PHP 8.0.0value and encoding became nullable.
  • PHP 7.2.0value may now be an array; previously only strings were accepted.

mb_check_encoding() answers exactly one question: are these bytes a legal sequence in this encoding? It converts nothing and guesses nothing — you name the encoding, it says yes or no.

Reach for it at the edges of your program: form input, uploaded CSV files, rows pulled out of a legacy database, anything read from a socket. Invalid UTF-8 travels quietly through your code until it meets something strict, and then the failure surfaces far from its cause — json_encode() returns false, a database insert is rejected, or a response body truncates mid-page. Validating on arrival turns that into an obvious rejection at the door.

Since PHP 7.2 it accepts an array and walks it recursively, validating both keys and values, so mb_check_encoding($_POST, 'UTF-8') gates an entire request in one call.

Watch the asymmetry between encodings. Single-byte encodings such as ISO-8859-1 or Windows-1252 assign a meaning to every possible byte, so a check against them is always true and tells you nothing at all. Only variable-width encodings — UTF-8, Shift_JIS, EUC-JP — have sequences that can genuinely be malformed.

When a string fails, you have two sensible moves: reject it, or repair it with mb_scrub() (replace the bad bytes) or mb_convert_encoding() (if you know what encoding it really is).

Example

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

When to use it

  • Reject a form submission that contains invalid UTF-8 before it reaches the database.
  • Verify an uploaded CSV really is UTF-8 before parsing it row by row.
  • Guard an API payload so json_encode() cannot silently return false on malformed bytes.
  • Decide, per row of a legacy import, whether to convert from Windows-1252 or keep as-is.

Frequently asked questions

How do I check if a string is valid UTF-8 in PHP?

Call mb_check_encoding($string, 'UTF-8') — it returns true only when every byte forms a legal UTF-8 sequence. Always pass 'UTF-8' explicitly rather than relying on the internal encoding, so the result does not change when someone edits php.ini.

What is the difference between mb_check_encoding and mb_detect_encoding?

mb_check_encoding() verifies a string against an encoding you name and returns a boolean; mb_detect_encoding() guesses which encoding a string is in and returns a name. Use check when you know what the data should be, and detect only when you genuinely have no idea.

Why does mb_check_encoding always return true for ISO-8859-1?

ISO-8859-1 maps all 256 possible byte values to characters, so no byte sequence can be invalid in it. Validation is only informative for variable-width encodings such as UTF-8, Shift_JIS or EUC-JP.

More examples

Repair input that fails the check

The byte 0x80 is not valid UTF-8, so the first check fails. Interpreted as Windows-1252 that byte is the euro sign, so the conversion produces "price: 100€" and the second check returns true. This is the standard shape of an import routine: check, convert only if needed, check again.

Example · php
<?php
$raw = "price: 100\x80";

if (!mb_check_encoding($raw, 'UTF-8')) {
    $raw = mb_convert_encoding($raw, 'UTF-8', 'Windows-1252');
}

echo $raw, "\n";
var_dump(mb_check_encoding($raw, 'UTF-8'));

Why json_encode() suddenly returns false

json_encode() refuses any string that is not valid UTF-8 and returns false rather than throwing, so the failure is easy to miss. mb_check_encoding() identifies the offending value before you ever get to the encoder, and json_last_error_msg() confirms the same cause.

Example · php
<?php
$bad = "caf\xE9";   // Latin-1 é, not UTF-8

var_dump(mb_check_encoding($bad, 'UTF-8'));
var_dump(json_encode(['x' => $bad]));
echo json_last_error_msg(), "\n";

Single-byte encodings always pass

Every byte has a meaning in ISO-8859-1, so the check is true for arbitrary binary garbage — a true result there proves nothing. Only variable-width encodings such as UTF-8 and Shift_JIS can report a malformed sequence, which is why validation is only meaningful against those.

Example · php
<?php
$random = "\x00\xFF\x80\x41\xC3";

var_dump(mb_check_encoding($random, 'ISO-8859-1'));
var_dump(mb_check_encoding($random, 'UTF-8'));
var_dump(mb_check_encoding($random, 'Shift_JIS'));

Discussion

  • Be the first to comment on this lesson.