Что делают модификаторы 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 имеет такое же минимальное объяснение, но без примеров. Я погуглил безуспешно.


person Luis Siquot    schedule 06.12.2012    source источник
comment
Вариант использования на самом деле довольно прост: используйте соответствующий флаг в зависимости от того, в какой диалект XML / HTML вы вводите значение. Однако этот вопрос сводится к следующему: каковы различия в правилах экранирования диалектов HTML / XML? Это хороший вопрос.   -  person deceze♦    schedule 06.12.2012
comment
спасибо @deceze, в моем конкретном случае (поскольку авторская разработка именно так) то, что объявлено, и проверяемый текст много раз не совпадают. Я исследую эти флаги, чтобы увидеть, могут ли они чем-то помочь.   -  person Luis Siquot    schedule 06.12.2012


Ответы (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)
  • Запретить 
 для 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
comment
Ух ты, PHP действительно удалось облажаться. Хотя отличный ответ! - person Mahn; 07.03.2013
comment
Обратите внимание, что хотя в документе не рекомендуется использовать ENT_IGNORE в целях безопасности (php.net/manual /en/function.htmlspecialchars.php), другие константы доступны только начиная с PHP 5.4.0, тогда как ENT_IGNORE уже есть в PHP 5.3.0. - person jeromej; 19.04.2014
comment
Можно комбинировать ENT_QUOTES с ENT_HTML5 как таковое: htmlspecialchars('<"">Test\'\'', ENT_QUOTES | ENT_HTML5) - это фактически означает, что нужно переводить как двойные, так и одинарные кавычки, но для одинарных кавычек используйте более приятный &apos; вместо числового &#039;. - person Michael Butler; 05.12.2019