Signature
mb_decode_numericentity(string $string, array $map, ?string $encoding = null): stringPurpose
mb_decode_numericentity() converts HTML numeric character references, such as é, into the characters they stand for. It is the counterpart of mb_encode_numericentity(). You need it when text arrives with accented letters, currency symbols or other non-ASCII characters written as numeric references, and you want a normal string again.
The function does not decode every reference blindly. You pass a conversion map that describes which code ranges are eligible. References outside those ranges stay as written.
Signature
Parameters and defaults
$string: the text that may contain numeric references.$map: a flat array of integers. It is read in groups of four values per rule:start_code,end_code,offsetandmask. The start and end values define the code area to convert. The offset and mask let you shift and mask the number, which is mainly useful for custom schemes.$encoding: the character encoding of the string and the result. The default isnull, which means the current internal encoding is used. Passing'UTF-8'explicitly makes the code independent of configuration.
Return value and failures
The function returns the converted string. If nothing matches, the text comes back unchanged.
It throws a ValueError if $encoding is not a valid encoding name. Since PHP 8.4.0 it also throws a ValueError if $map contains a value that is not an int, float, bool, null or numeric string, that is, a value that cannot be implicitly converted to an integer. Before PHP 8.0.0 an invalid encoding produced a warning instead; with PHP 8.4 you can simply catch the exception.
Example 1: decode references in a UTF-8 string
The common map [0x80, 0x10FFFF, 0, 0x1FFFFF] covers everything above ASCII, with no offset and a mask wide enough for any Unicode code point.
$map = [0x80, 0x10FFFF, 0, 0x1FFFFF];
echo mb_decode_numericentity('Café €5', $map, 'UTF-8'), "\n";Café €5
Example 2: the map limits what is decoded
Here the only rule covers 0x41 to 0x5A, the uppercase ASCII letters. The reference for A (65) is inside the range and is decoded. The reference for lowercase a (97) is outside it and is left alone.
$map = [0x41, 0x5A, 0, 0xFF];
echo mb_decode_numericentity('Aa', $map, 'UTF-8'), "\n";Aa
Example 3: round trip with the encoder
Using the same map for both functions gives a reliable round trip. The encoder produces references for non-ASCII characters and the decoder restores the original text.
$map = [0x80, 0x10FFFF, 0, 0x1FFFFF];
$original = 'Привет';
$encoded = mb_encode_numericentity($original, $map, 'UTF-8');
$decoded = mb_decode_numericentity($encoded, $map, 'UTF-8');
echo $encoded, "\n";
echo $decoded, "\n";
var_dump($decoded === $original);Привет Привет bool(true)
Edge cases
- A string with no references is returned as it is.
- A reference whose number lies outside every rule in the map is preserved literally, as Example 2 shows.
- Several rules can be placed one after another in the same flat array, four values each, to decode more than one range.
- The encoding matters. The result is built in the encoding you give, so the string you pass in and the encoding name should agree.
Common mistakes
- Treating the map as optional or as a list of characters. It is a flat array of numeric rules, four integers per rule, not a list of characters to decode.
- Choosing a range that is too narrow. If a reference stays undecoded, check whether its number falls between the start and end values of some rule.
- Putting non-numeric values in the map. In PHP 8.4 a value that cannot be converted to an integer throws a
ValueError, so do not assume it is silently ignored. - Relying on the default encoding. If the internal encoding differs from the data, the result can be wrong. Pass
'UTF-8'when you work with UTF-8 text. - Expecting it to decode named entities. References like
éor&are not numeric references. Usehtml_entity_decode()for those. - Assuming decoded text is safe HTML. Decoding
<script>can produce markup characters. Escape output properly after decoding when it is shown in a page.
Related functions
mb_encode_numericentity(): the opposite conversion, from characters to numeric references.html_entity_decode(): decodes named and numeric HTML entities using HTML rules.mb_convert_encoding(): converts text between character encodings.mb_internal_encoding(): reads or sets the default encoding thatnullrefers to.
Recap
Use mb_decode_numericentity() to turn numeric references into real characters inside the code ranges you describe in $map. Give the encoding explicitly, remember that out-of-range references are left unchanged, and expect a ValueError for an invalid encoding or, in PHP 8.4, for map values that are not numeric.
Tested examples
$map = [0x80, 0x10FFFF, 0, 0x1FFFFF];
echo mb_decode_numericentity('Café €5', $map, 'UTF-8'), "\n";
Café €5
$map = [0x41, 0x5A, 0, 0xFF];
echo mb_decode_numericentity('Aa', $map, 'UTF-8'), "\n";
Aa
$map = [0x80, 0x10FFFF, 0, 0x1FFFFF];
$original = 'Привет';
$encoded = mb_encode_numericentity($original, $map, 'UTF-8');
$decoded = mb_decode_numericentity($encoded, $map, 'UTF-8');
echo $encoded, "\n";
echo $decoded, "\n";
var_dump($decoded === $original);
Привет Привет bool(true)