Signature
get_html_translation_table(
int $table = HTML_SPECIALCHARS,
int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
string $encoding = "UTF-8"
): arrayPurpose
get_html_translation_table() gives you the exact map that htmlspecialchars() and htmlentities() consult internally. The result is an ordinary PHP array. Each key is a single original character and each value is the entity string that replaces it. Looking at the table is useful when you want to inspect what a given flag combination will encode, build a custom replacement with strtr(), or check what a document type such as HTML 4.01 or HTML5 supports.
Signature
Parameters and defaults
$tableselects the table.HTML_SPECIALCHARSis the small table used byhtmlspecialchars().HTML_ENTITIESis the much larger table used byhtmlentities().$flagsis a bitmask. Quote flags decide whether quotes are included:ENT_COMPATincludes double quotes only,ENT_QUOTESincludes both quote types, andENT_NOQUOTESincludes neither. A document-type flag chooses the entity set:ENT_HTML401,ENT_XML1,ENT_XHTMLorENT_HTML5.ENT_SUBSTITUTEis part of the default value as well.$encodingnames the character set. The default isUTF-8. Other supported charsets includeISO-8859-1,ISO-8859-15,cp1252,Shift_JISandEUC-JP. An empty string asks PHP to detect the encoding, which the manual marks as not recommended.
The manual's changelog records one change: since PHP 8.1.0 the default for $flags is ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 instead of ENT_COMPAT. If you rely on the default and the code must behave the same on old and new versions, pass the flags explicitly.
Return value and failure cases
The function returns an array with the original characters as keys and entities as values. For an unrecognized charset, PHP emits a warning and uses the default encoding instead. The function does not return false.
The manual also notes that a character can be written as an entity in several ways, for example ", " or ". The table lists only the form that the two encoding functions actually produce.
Example 1: the default special-characters table
The default table has five entries. The example sorts the keys so that the printed order is obvious.
$table = get_html_translation_table();
ksort($table);
echo json_encode($table, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;{"\"":""","&":"&","'":"'","<":"<",">":">"}
Example 2: how flags change the table
Quote flags change how many entries the special-characters table holds. The document type changes the form of the single-quote entity.
$counts = [
'compat' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_COMPAT | ENT_HTML401)),
'quotes' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES | ENT_HTML401)),
'noquotes' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES | ENT_HTML401)),
];
echo json_encode($counts), PHP_EOL;
$html5 = get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES | ENT_HTML5);
echo $html5["'"], PHP_EOL;{"compat":4,"quotes":5,"noquotes":3}
'
Example 3: using the full entity table
The HTML_ENTITIES table covers named entities for accented letters and symbols. Passing it to strtr() performs the same kind of substitution as htmlentities() with matching flags.
$table = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES | ENT_HTML401, 'UTF-8');
echo json_encode([$table['é'], $table['©'], count($table) > 5], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo strtr('café <b>', $table), PHP_EOL;["é","©",true] café <b>
Edge cases
- With
ENT_NOQUOTESneither quote character appears, so the table has only&,<and>. - The same character can map to a different entity in a different document type. The single quote is the common case: the HTML5 table uses
'. HTML_ENTITIESis large and its size depends on the document type, so do not hard-code its count.- Keys are characters in the chosen encoding. In UTF-8 a key such as
éis a multibyte string, while inISO-8859-1it is a single byte.
Common mistakes
- Relying on the default flags across versions. The default changed in PHP 8.1.0, which affects whether single quotes are in the table.
- Treating the table as a decoder. Flipping it with
array_flip()only covers the entity forms in the table. Usehtml_entity_decode()orhtmlspecialchars_decode()for real decoding, since they accept more forms. - Mixing flags between calls. Building a table with one set of flags and then escaping with another produces inconsistent output.
- Using it as the escaping step itself. For output escaping, call
htmlspecialchars()directly. It is the supported and clearer API. - Forgetting the encoding. Reading a table for
UTF-8and applying it to text in another charset gives wrong results.
Related functions
htmlspecialchars()converts the special characters to entities.htmlentities()converts all applicable characters to entities.html_entity_decode()converts entities back to characters.
Recap
get_html_translation_table() returns an array of characters to entities for the table, flags and encoding you choose. Pass flags explicitly, remember that quote flags and document type change the contents, and use the dedicated encode and decode functions for real escaping work.
Tested examples
$table = get_html_translation_table();
ksort($table);
echo json_encode($table, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
{"\"":""","&":"&","'":"'","<":"<",">":">"}
$counts = [
'compat' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_COMPAT | ENT_HTML401)),
'quotes' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES | ENT_HTML401)),
'noquotes' => count(get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES | ENT_HTML401)),
];
echo json_encode($counts), PHP_EOL;
$html5 = get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES | ENT_HTML5);
echo $html5["'"], PHP_EOL;
{"compat":4,"quotes":5,"noquotes":3}
'
$table = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES | ENT_HTML401, 'UTF-8');
echo json_encode([$table['é'], $table['©'], count($table) > 5], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
echo strtr('café <b>', $table), PHP_EOL;
["é","©",true] café <b>