mb_internal_encoding

Gets or sets the default character encoding used by the mbstring functions.

Signature
mb_internal_encoding(?string $encoding = null): string|bool
  • Added in PHP 4.0.6

Parameters

ParameterTypeDescription
$encodingoptional?string= nullThe encoding name to set as the mbstring default. If omitted or null, the current setting is returned instead of changed.

Return value

string|boolWhen encoding is given, true on success or false on failure. When omitted or null, the name of the current internal encoding as a string.

Errors

Throws a ValueError as of PHP 8.0 when the encoding name is not recognised by mbstring.

Changelog

  • PHP 8.0.0encoding became nullable.
  • PHP 8.0.0A ValueError is thrown when encoding is invalid; previously an E_WARNING was emitted and false returned.

mb_internal_encoding() is a two-in-one accessor: called with a name it sets the mbstring default, called with nothing it returns the current one. That default is what every mbstring function falls back to when you omit its encoding argument — mb_strlen(), mb_substr(), mb_str_split(), mb_convert_case() and the rest.

On modern PHP the value already comes from the default_charset ini setting, which is UTF-8 out of the box, so calling this at the top of a bootstrap file is usually belt-and-braces rather than a fix. Where it earns its place is defensive: setting it explicitly means your code behaves the same on a host whose php.ini says something else.

The setting is process-wide and lasts for the rest of the request. That makes it convenient and dangerous in equal measure. Changing it inside a function to handle one legacy string silently changes the behaviour of every later mbstring call in the request, including in library code you did not write. If you need a different encoding for one operation, pass it as that function's encoding argument instead. If you truly must switch the global, capture the old value first and restore it.

It has no effect on preg_* with the /u modifier, on mb_ereg_*, or on plain byte functions such as strlen().

Example

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

When to use it

  • Pin UTF-8 at application bootstrap so behaviour does not depend on the host's php.ini.
  • Read the current setting when logging or debugging an encoding problem in production.
  • Temporarily switch to a legacy encoding for a batch import, then restore the previous value.
  • Assert at startup that the runtime is configured for UTF-8 before processing user text.

Frequently asked questions

Do I still need to call mb_internal_encoding('UTF-8') in PHP 8?

Usually not — the internal encoding defaults to the default_charset ini setting, which is UTF-8. Setting it explicitly at bootstrap is still worth doing if you deploy to hosts whose php.ini you do not control.

What is the difference between mb_internal_encoding and default_charset?

default_charset is the ini setting that seeds the internal encoding at startup and is also used for HTTP Content-Type headers, while mb_internal_encoding() reads or changes the mbstring default for the current request only.

Does mb_internal_encoding affect preg_match or strlen?

No. It only affects mbstring functions that take an optional encoding argument. Byte functions such as strlen() and PCRE with the /u modifier are unaffected.

More examples

Save and restore around a legacy operation

"Köln" is 5 bytes as Latin-1 and reports 5 characters while that is the default; back on UTF-8 the original string reports 4. Capturing the previous value and putting it back is the only safe way to touch a process-wide setting, because anything running after you inherits whatever you leave behind.

Example · php
<?php
$previous = mb_internal_encoding();

mb_internal_encoding('ISO-8859-1');
$legacy = mb_convert_encoding("Köln", 'ISO-8859-1', 'UTF-8');
echo mb_strlen($legacy), " chars while Latin-1 is the default\n";

mb_internal_encoding($previous);
echo mb_internal_encoding(), " restored\n";
echo mb_strlen("Köln"), " chars again\n";

An invalid encoding name throws

A successful set returns true. Since PHP 8.0 an unrecognised name throws a ValueError instead of emitting a warning and returning false, so a typo in a config value fails loudly. The setting is left untouched when the call throws, as the final line confirms.

Example · php
<?php
var_dump(mb_internal_encoding('UTF-8'));

try {
    mb_internal_encoding('NOT-A-CHARSET');
} catch (ValueError $e) {
    echo get_class($e), ": ", $e->getMessage(), "\n";
}

echo mb_internal_encoding(), "\n";

Per-call encoding beats changing the global

The same seven bytes count as six characters in UTF-8 and seven in Latin-1. Passing the encoding to the individual call gets the alternative reading without disturbing the global, which stays UTF-8 for everything else in the request.

Example · php
<?php
mb_internal_encoding('UTF-8');
$s = "häuser";

echo mb_strlen($s), "\n";                 // uses the global
echo mb_strlen($s, 'ISO-8859-1'), "\n";   // same bytes, other reading
echo mb_substr($s, 0, 3, 'UTF-8'), "\n";
echo mb_internal_encoding(), "\n";        // still UTF-8

Discussion

  • Be the first to comment on this lesson.