Ответ 1
Я начал задаваться вопросом, какое поведение имеют эти константы, когда я видел эти константы на странице 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
) - Disallow

для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_ * следует использовать для htmlentities?
Если ваш текстовый редактор или база данных настолько дрянной, что вы не можете включать символы, отличные от US-ASCII (например, UTF-8), вы можете использовать htmlentities. В противном случае сохраните несколько байтов и вместо этого используйте htmlspecialchars (см. Выше).
Если вам нужно использовать ENT_HTML401
, ENT_HTML5
или что-то еще, зависит от того, как ваша страница будет обслуживаться. Когда у вас есть страница HTML5 (<!doctype html>
), используйте ENT_HTML5
. XHTML или XML? Используйте соответствующие ENT_XHTML
или ENT_XML1
. Не используйте doctype или plain ol 'HTML4, используйте ENT_HTML401
(который по умолчанию опущен).
Должен ли я использовать ENT_DISALLOWED, ENT_IGNORE или ENT_SUBSTITUTE?
По умолчанию байтовые последовательности недействительны для заданного набора символовудаляются. Чтобы иметь �
вместо недопустимой последовательности байтов, укажите ENT_SUBSTITUTE
. (обратите внимание, что &#FFFD;
отображается для кодировок, отличных от UTF-8). Когда вы укажете ENT_IGNORE
, хотя эти символы не отображаются, даже если вы указали ENT_SUBSTITUTE
.
Недопустимые символы для типа документа заменяются одним и тем же символом замены (или его сущностью) выше, когда указан ENT_DISALLOWED
. Это происходит независимо от наличия ENT_IGNORE
set (что не имеет ничего общего с недопустимыми символами для doctypes).