Что делают модификаторы ENT_HTML5, ENT_HTML401, … на html_entity_decode?

Поскольку php 5.4 html_entity_decode вводит четыре новых флага с минимальным объяснением

ENT_HTML401 Handle code as HTML 4.01. ENT_XML1 Handle code as XML 1. ENT_XHTML Handle code as XHTML. ENT_HTML5 Handle code as HTML 5. 

Я хочу понять, для чего они нужны. В каких случаях они значительны?

Мое предположение (но могу ли я ошибиться) заключается в том, что любой другой стандарт кодирует некоторые необычные символы, а другие нет, поэтому для того, чтобы уважать это, они здесь.

Мои исследования: htmlentities имеет одинаковое минимальное объяснение, без примеров. Мне не повезло.

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

  • Это влияет на то, какие числовые объекты будут декодированы или нет. Например,  получает декодированный нечитаемый / недопустимый символ для ENT_HTML401 и ENT_XHTML и ENT_XML1 . Однако для ENT_HTML5 это считается недопустимым символом, и, следовательно, он остается  , ( Функция C unicode_cp_is_allowed )
  • При включенном ENT_SUBSTITUTE недопустимые последовательности блоков кода для заданного набора символов заменяются на . (не зависит от типа документа!)
  • При включенном ENT_DISALLOWED кодовые точки , которые запрещены для указанного типа документа , заменяются на . (не зависит от кодировки!)
  • С ENT_IGNORE одинаковые неправильные последовательности ENT_SUBSTITUTE кода из ENT_SUBSTITUTE и не производится замена (зависит от выбора типа документа, например ENT_HTML5 )
  • Disallow 
 для ENT_HTML5 ( строка 976 )
  • ENT_XHTML разделяет карту сущности с ENT_HTML401 . Единственное различие заключается в том, что ' будет преобразован в апостроф с ENT_XHTML то время как ENT_HTML401 не преобразует его (см. эту строку )
  • ENT_HTML401 и ENT_XHTML используют точно такую ​​же карту сущности (минус отличие от предыдущей точки). ENT_HTML5 использует свою собственную карту. Другие (в настоящее время ENT_XML1 ) имеют очень ограниченную карту декодирования ( > ENT_XML1 & , < 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 ENT_HTML401 | ENT_COMPAT который имеет ENT_HTML401 | ENT_COMPAT же разницу, что и объекты HTML5, но также и то, что цитаты больше не исчезают! Кроме того, это избыточный код. htmlspecialchars , которые должны быть закодированы с помощью htmlspecialchars , одинаковы для всех ENT_HTML401 , ENT_HTML5 и т. Д.

ENT_QUOTES этого используйте ENT_COMPAT или ENT_QUOTES . Последнее также работает, когда вы используете апострофы для атрибутов ( value='foo' ). Если у вас есть только два аргумента для htmlspecialchars , не включайте аргумент вообще, поскольку он по умолчанию ( ENT_HTML401 – 0, помните?).

Когда вы хотите напечатать что-то на странице (между тегами, а не атрибутами), не имеет значения, какой из них вы выберете, так как он будет иметь равный эффект. Достаточно даже использовать ENT_NOQUOTES | ENT_HTML401 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 (что не имеет ничего общего с недопустимыми символами для дотипов).