html_entity_decode上的ENT_HTML5,ENT_HTML401,…修饰符是做什么的?

由于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有相同的最小的解释,也没有例子。 我没有运气Googlesearch。

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

基本上,这些常量影响某些实体是否被编码(或解码为html_entity_decode )。 最明显的效果是,撇号( ' )是否被编码为' (对于ENT_HTML401 )或' (为他人)。 类似地,它确定是否' 在使用html_entity_decode时被解码或不被解码。 ( '总是被解码)。

所有用法可以在ext / standard / html.c及其头文件中find。 从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_replaceENT_HTML_DOC_以获得他们的PHP常量名)

我开始寻找这些常量的所有事件,并且可以共享ENT_*常量的行为:

  • 它影响哪些数字实体将被解码或不。 例如,  被解码为ENT_HTML401ENT_XHTMLENT_XML1的不可读/无效字符。 但是,对于ENT_HTML5 ,这被认为是无效的字符,因此它保持 。 ( C函数unicode_cp_is_allowed )
  • 启用ENT_SUBSTITUTE指定字符集的无效代码单元序列被replace为 。 (不依赖于文件types!)
  • 在启用ENT_DISALLOWED指定文档types不允许的代码点将被replace为 。 (不依赖于字符集!)
  • 使用ENT_IGNOREENT_IGNORE中的相同无效代码单元序列被删除,不会进行replace(取决于“文档types”的select,例如ENT_HTML5
  • 禁止
 对于ENT_HTML5 ( 第976行 )
  • ENT_XHTMLENT_HTML401共享实体图。 唯一的区别是' 将被转换为ENT_XHTML的撇号,而ENT_HTML401不会将其转换(请参阅此行 )
  • ENT_HTML401ENT_XHTML使用完全相同的实体映射(减去与前一点的差异)。 ENT_HTML5使用自己的地图。 其他人(当前是ENT_XML1 )具有非常有限的解码图( >&< ENT_XML1 ' ,及其数字等同物)。 (请参阅C函数unescape_inverse_map )
  • 注意前一点:只有less数实体必须被转义(想到htmlspecialchars ),除了ENT_HTML401之外,所有的实体映射都将使用与ENT_XML1相同的ENT_HTML401 。 那个人不会使用' ,但是'

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

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

当用ENT_COMPAT(默认)或ENT_NOQUOTES使用htmlspecialchars ,select哪一个并不重要(见下文)。 我在这里看到了一些答案,可以归结为:

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

这是不安全的 。 它将覆盖默认值ENT_HTML401 | ENT_COMPAT ENT_HTML401 | ENT_COMPAT与HTML5实体有所不同,但引号也不会被转义! 另外,这是多余的代码。 必须由htmlspecialchars编码的htmlspecialchars对于所有ENT_HTML401ENT_HTML5等都是相同的

只需使用ENT_COMPATENT_QUOTES 。 后者也适用于使用撇号属性( value='foo' )。 如果您只有两个参数htmlspecialchars ,请不要包含参数,因为它是默认的( ENT_HTML401是0,请记住?)。

当你想在页面上打印一些东西(标签之间而不是属性)时,你select哪一个并不重要,因为它具有相同的效果。 甚至足以使用ENT_NOQUOTES | ENT_HTML401 ENT_NOQUOTES | ENT_HTML401等于数字值0

另请参阅下面关于ENT_SUBTITUTE和ENT_DISALLOWED的内容。

我应该使用什么ENT_ *

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

无论您需要使用ENT_HTML401ENT_HTML5还是其他内容,都取决于您的网页的投放方式。 当您有HTML5页面( <!doctype html> )时,请使用ENT_HTML5 。 XHTML或XML? 使用相应的ENT_XHTMLENT_XML1 。 没有文档或普通的HTML4,使用ENT_HTML401 (这是省略时的默认)。

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

默认情况下,删除给定字符集无效的字节序列。 代替无效的字节序列,请指定ENT_SUBSTITUTE 。 (请注意&#FFFD;显示为非UTF-8字符集)。 当您指定ENT_IGNORE即使您指定了ENT_IGNORE ,也不会显示这些字符。

指定ENT_DISALLOWED时, 文档types的无效字符被上面相同的replace字符(或其实体)替代。 无论ENT_IGNORE设置了ENT_IGNORE (这与ENT_IGNORE无效字符无关), ENT_IGNORE发生这种情况。