Я начал задаваться вопросом, какое поведение имеют эти константы, когда я увидел эти константы на странице htmlspecialchars. Документация была хламом, поэтому я начал копаться в исходном коде PHP.
По сути, эти константы влияют на то, кодируются ли определенные объекты (или декодируются для html_entity_decode
). Наиболее очевидный эффект заключается в том, закодирован ли апостроф ('
) в '
(для ENT_HTML401
) или '
(для других). Точно так же он определяет, декодируется ли '
или нет при использовании html_entity_decode
. ('
всегда декодируется).
Все варианты использования можно найти в ext / standard / html.c и его заголовочном файле. Из ext / standard / html.h:
#define ENT_HTML_DOC_HTML401 0
#define ENT_HTML_DOC_XML1 16
#define ENT_HTML_DOC_XHTML 32
#define ENT_HTML_DOC_HTML5 (16|32)
(замените ENT_HTML_DOC_
на ENT_
, чтобы получить их имена констант PHP)
Я начал искать все вхождения этих констант и могу рассказать следующее о поведении констант ENT_*
:
- Это влияет на то, какие числовые объекты будут декодированы или нет. Например,

декодируется в нечитаемый / недопустимый символ для ENT_HTML401
, а также ENT_XHTML
и ENT_XML1
. Однако для ENT_HTML5
это считается недопустимым символом и, следовательно, остается 
. (C-функция unicode_cp_is_allowed)
- Если
ENT_SUBSTITUTE
включен, недопустимые последовательности кодовых единиц для указанного набора символов заменяются на �
. (не зависит от типа документа!)
- Если
ENT_DISALLOWED
включен, кодовые точки, которые запрещены для указанного типа документа, заменяются на �
. (не зависит от кодировки!)
- С
ENT_IGNORE
удаляются те же неверные последовательности кодовых единиц из ENT_SUBSTITUTE
, и замена не производится (зависит от выбора «типа документа», например, ENT_HTML5
)
- Запретить

для ENT_HTML5
(строка 976)
ENT_XHTML
разделяет карту объекта с ENT_HTML401
. Единственная разница в том, что '
будет преобразован в апостроф с ENT_XHTML
, а ENT_HTML401
не преобразует его (см. эта строка)
ENT_HTML401
и ENT_XHTML
используют одну и ту же карту сущностей (за вычетом отличий от предыдущего пункта). ENT_HTML5
использует собственную карту. Другие (в настоящее время ENT_XML1
) имеют очень ограниченную карту декодирования (>
, &
, <
, '
, "
и их числовые эквиваленты). (см. функцию C unescape_inverse_map)
- Примечание к предыдущему пункту: когда нужно экранировать только несколько сущностей (подумайте о
htmlspecialchars
), все карты сущностей будут использовать ту же самую карту, что и ENT_XML1
, за исключением ENT_HTML401
. Этот не будет использовать '
, но '
.
Это охватывает почти все. Я не собираюсь перечислять все различия сущностей, вместо этого я хотел бы указать на https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables для некоторых текстовых файлов, содержащих сопоставления для каждого типа.
Какой ENT_ * я должен использовать для htmlspecialchars?
При использовании htmlspecialchars
с ENT_COMPAT (по умолчанию) или ENT_NOQUOTES не имеет значения, какой из них вы выберете (см. Ниже). Я видел здесь несколько ответов на SO, которые сводятся к следующему:
<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" >
Это небезопасно. Он переопределит значение по умолчанию ENT_HTML401 | ENT_COMPAT
, которое отличается тем, что используются объекты HTML5, но также то, что кавычки больше не экранируются! Кроме того, это избыточный код. Сущности, которые должны быть закодированы с помощью htmlspecialchars
, одинаковы для всех ENT_HTML401
, ENT_HTML5
и т. Д.
Просто используйте вместо этого ENT_COMPAT
или ENT_QUOTES
. Последний также работает, когда вы используете апострофы для атрибутов (value='foo'
). Если у вас есть только два аргумента для htmlspecialchars
, не включайте этот аргумент вообще, поскольку он является значением по умолчанию (ENT_HTML401
равно 0, помните?).
Когда вы хотите напечатать что-то на странице (между тегами, а не атрибутами), совершенно не имеет значения, какой из них вы выберете, поскольку это будет иметь одинаковый эффект. Достаточно даже использовать ENT_NOQUOTES | ENT_HTML401
, что равно числовому значению 0
.
См. Также ниже о ENT_SUBTITUTE и ENT_DISALLOWED.
Какой ENT_ * я должен использовать для здоровья?
Если ваш текстовый редактор или база данных настолько плохи, что вы не можете включать символы, отличные от US-ASCII (например, UTF-8), вы можете использовать htmlentities. В противном случае сохраните несколько байтов и вместо этого используйте htmlspecialchars (см. Выше).
Нужно ли вам использовать ENT_HTML401
, ENT_HTML5
или что-то еще, зависит от того, как обслуживается ваша страница. Если у вас есть страница HTML5 (<!doctype html>
), используйте ENT_HTML5
. XHTML или XML? Используйте соответствующий ENT_XHTML
или ENT_XML1
. Без doctype или простого HTML4 используйте ENT_HTML401
(это значение по умолчанию, если оно опущено).
Что мне следует использовать: ENT_DISALLOWED, ENT_IGNORE или ENT_SUBSTITUTE?
По умолчанию байтовые последовательности, недопустимые для данного набора символов, удаляются. Чтобы использовать �
вместо недопустимой последовательности байтов, укажите ENT_SUBSTITUTE
. (обратите внимание, что &#FFFD;
отображается для кодировок, отличных от UTF-8). Однако, когда вы указываете ENT_IGNORE
, эти символы не отображаются, даже если вы указали ENT_SUBSTITUTE
.
Недопустимые символы для типа документа заменяются тем же символом замены (или его сущностью), указанным выше, если указано ENT_DISALLOWED
. Это происходит независимо от того, установлен ли ENT_IGNORE
(который не имеет ничего общего с недопустимыми символами для типов документа).
person
Lekensteyn
schedule
25.01.2013