html_entity_decode上的ENT_HTML5,ENT_HTML401,...修饰符有什么作用?

Lui*_*uot 49 html php html-entities htmlspecialchars

由于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. 
Run Code Online (Sandbox Code Playgroud)

我想了解它们的用途.在哪些情况下它们是重要的?

我猜,(但可能我错了)是任何不同的标准,编码一些不寻常的字符,但任何其他不,所以为了尊重它,他们在这里.

我的研究:htmlentities有相同的最小解释,也没有例子.我用Google搜索没有运气.

Lek*_*eyn 86

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

基本上,这些常数会影响某些实体是否编码(或解码html_entity_decode).最明显的效果是撇号(')是编码为'(for ENT_HTML401)还是'(for others).类似地,它确定'在使用时是否被解码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)
Run Code Online (Sandbox Code Playgroud)

(替换ENT_HTML_DOC_ENT_得到他们的PHP常量名)

我开始寻找所有这些常量的出现,并且可以在ENT_*常量的行为上分享以下内容:

  • 它会影响哪些数字实体将被解码.例如,被解码为不可读/无效的字符ENT_HTML401,ENT_XHTMLENT_XML1.对于ENT_HTML5然而,这被视为无效字符,因此它停留.(C函数unicode_cp_is_allowed)
  • ENT_SUBSTITUTE启用,无效的代码单元序列中要指定的字符集被替换?.(不依赖于文档类型!)
  • ENT_DISALLOWED启用,代码点被禁止指定文档类型将被替换?.(不依赖于charset!)
  • 使用ENT_IGNORE,ENT_SUBSTITUTE删除相同的无效代码单元序列并且不进行替换(取决于"文档类型"的选择,例如ENT_HTML5)
  • 禁止
ENT_HTML5(线976)
  • ENT_XHTML与实体地图共享ENT_HTML401.唯一的区别是,'将被转换成一个单引号用ENT_XHTML,而ENT_HTML401不会转换(见本线)
  • ENT_HTML401ENT_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?

当使用htmlspecialcharsENT_COMPAT(默认)或ENT_NOQUOTES时,您选择哪一个并不重要(见下文).我在这里看到了一些答案,归结为:

<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" >
Run Code Online (Sandbox Code Playgroud)

这是不安全的.它将覆盖默认值ENT_HTML401 | ENT_COMPAT,其具有的区别在于HTML5实体使用,但认为引号不再逃脱!另外,这是冗余代码.必须由被编码的实体htmlspecialchars是所有相同的ENT_HTML401,ENT_HTML5

只需使用ENT_COMPATENT_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_XHTMLENT_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设置(这与doctypes的无效字符无关),都会发生这种情况.

  • 哇,PHP确实设法搞砸了这个.很棒的答案! (7认同)