ENT_HTML401,ENT_HTML5是什么?修改器html_entity_decode做什么?我应该使用什么ENT_*来表示htmlspecialchars?我应该使用什么ENT_*作为 htmlentities?我应该使用ENT_DISALLOWED、ENT_IGNORE还是ENT_SUBSTITUTE?

2022-08-30 09:59:16

从 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有相同的最小解释,也没有例子。我没有运气地谷歌。


答案 1

当我在htmlspecialchars页面上看到这些常量时,我开始想知道这些常量有什么行为。文档是垃圾,所以我开始挖掘PHP的源代码。

基本上,这些常量会影响某些实体是否被编码(或解码为 )。最明显的效果是撇号 () 是编码为 (for ) 还是 (for other)。同样,它确定在使用 时是否被解码。(始终被解码)。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)

(替换为以获取其 PHP 常量名称)ENT_HTML_DOC_ENT_

我开始寻找这些常量的所有出现次数,并且可以分享以下有关常量行为的信息:ENT_*

  • 它会影响将解码或不解码的数字实体。例如,被解码为 和 和 的不可读/无效字符。但是,这被认为是一个无效字符,因此它保持不变。(C 函数unicode_cp_is_allowedENT_HTML401ENT_XHTMLENT_XML1ENT_HTML5)
  • 启用后,指定字符集的无效代码单位序列将替换为 。(不依赖于文档类型!ENT_SUBSTITUTE
  • 启用后,指定文档类型不允许的码位将替换为 。(不依赖于字符集!ENT_DISALLOWED
  • 使用 ,将删除相同的无效代码单元序列,并且不进行替换(取决于“文档类型”的选择,例如ENT_IGNOREENT_SUBSTITUTEENT_HTML5)
  • 禁止(第 976 行)
ENT_HTML5)
  • ENT_XHTML与 共享实体映射。唯一的区别是将转换为撇号,而不会将其转换(请参阅此行ENT_HTML401'ENT_XHTMLENT_HTML401)
  • ENT_HTML401并使用完全相同的实体映射(减去与上一点的差异)。 使用自己的地图。其他人(目前)有一个非常有限的解码映射(,,,,和他们的数字等价物)。(参见 C 函数unescape_inverse_mapENT_XHTMLENT_HTML5ENT_XML1>&<'")
  • 注意上一点:当只有几个实体必须转义时(想想),所有实体映射都将使用与 相同的实体,除了 .那个不会使用,但是.htmlspecialcharsENT_XML1ENT_HTML401''

这几乎涵盖了一切。我不打算列出所有实体差异,而是想指出 https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables 一些包含每种类型映射的文本文件。

我应该使用什么ENT_*来表示htmlspecialchars?

与ENT_COMPAT(默认)或ENT_NOQUOTES一起使用时,选择哪一个并不重要(见下文)。我在SO上看到了一些答案,可以归结为:htmlspecialchars

<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" >

这是不安全的。它将覆盖默认值,该默认值与使用HTML5实体的差异相同,但引号不再转义!此外,这是冗余代码。必须编码的实体对于所有 、 等都是相同的。ENT_HTML401 | ENT_COMPAThtmlspecialcharsENT_HTML401ENT_HTML5

只需使用或代替。当您对属性 () 使用撇号时,后者也有效。如果 只有 两个参数,则根本不包含该参数,因为它是默认值(是 0,还记得吗?)。ENT_COMPATENT_QUOTESvalue='foo'htmlspecialcharsENT_HTML401

当您想在页面上打印某些内容(在标签之间,而不是属性之间)时,选择哪一个根本不重要,因为它将具有相同的效果。使用等于数值甚至就足够了。ENT_NOQUOTES | ENT_HTML4010

另见下文,关于ENT_SUBTITUTE和ENT_DISALLOWED。

我应该使用什么ENT_*作为 htmlentities?

如果你的文本编辑器或数据库非常糟糕,以至于你不能包含非US-ASCII字符(例如UTF-8),你可以使用htmlentities。否则,请保存一些字节并改用 htmlspecialchars(见上文)。

您是否需要使用 ,或者其他内容取决于您的网页的投放方式。当您有 HTML5 页面 ()时,请使用 。XHTML 还是 XML?使用相应的 或 。如果没有 doctype 或 plain ol' HTML4,请使用(省略时为默认值)。ENT_HTML401ENT_HTML5<!doctype html>ENT_HTML5ENT_XHTMLENT_XML1ENT_HTML401

我应该使用ENT_DISALLOWED、ENT_IGNORE还是ENT_SUBSTITUTE?

默认情况下,将删除对给定字符集无效的字节序列。要用 代替无效的字节序列,请指定 。(请注意,对于非 UTF-8 字符集,将显示该字符集)。如果指定,则即使指定了 ,也不会显示这些字符。ENT_SUBSTITUTE&#FFFD;ENT_IGNOREENT_SUBSTITUTE

指定文档类型的无效字符时,将替换为上面的相同替换字符(或其实体)。无论是否设置了此设置(这与文档类型的无效字符无关),都会发生这种情况。ENT_DISALLOWEDENT_IGNORE


答案 2

推荐