【问题标题】:What do the ENT_HTML5, ENT_HTML401, ... modifiers on html_entity_decode do?html_entity_decode 上的 ENT_HTML5、ENT_HTML401、... 修饰符有什么作用?
【发布时间】:2012-11-24 14:01:48
【问题描述】:

自从 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 有相同的最小解释,也没有示例。我用谷歌搜索没有运气。

【问题讨论】:

  • 用例实际上非常简单:根据您将值放入的 XML/HTML 方言使用适当的标志。这个问题归结为:HTML/XML 方言转义规则有什么区别?这是个好问题。
  • 感谢@deceze,在我的特殊情况下,(因为创作就是这样)声明的内容和正在检查的文本多次不匹配。我正在调查这些标志,看看它们是否能以某种方式提供帮助。

标签: php html html-entities htmlspecialchars


【解决方案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_HTML401ENT_XHTMLENT_XML1 的不可读/无效字符。但是对于ENT_HTML5,这被认为是无效字符,因此它保持为。 (C function unicode_cp_is_allowed)
  • 启用ENT_SUBSTITUTE 后,指定字符集的无效代码单元序列将替换为。 (不取决于文档类型!)
  • 启用ENT_DISALLOWED 后,指定文档类型不允许的代码点将替换为。 (不依赖于字符集!)
  • 使用ENT_IGNORE,来自ENT_SUBSTITUTE 的相同无效代码单元序列将被删除并且不进行替换(取决于“文档类型”的选择,例如ENT_HTML5
  • 禁止 
 使用 ENT_HTML5 (line 976)
  • ENT_XHTMLENT_HTML401 共享实体映射。唯一的区别是' 将转换为带有ENT_XHTML 的撇号,而ENT_HTML401 不会转换它(参见this line
  • ENT_HTML401ENT_XHTML 使用完全相同的实体映射(减去与上一点的差异)。 ENT_HTML5 使用自己的地图。其他人(目前为ENT_XML1)的解码映射非常有限(>&<'" 及其数字等价物)。 (见C function unescape_inverse_map
  • 注意前一点:当只有少数实体必须转义时(想想htmlspecialchars),所有实体映射将使用与ENT_XML1 相同的实体,ENT_HTML401 除外。那个不会使用',而是'

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

htmlspecialchars 应该使用什么 ENT_*?

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

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

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

只需改用ENT_COMPATENT_QUOTES。当您对属性使用撇号 (value='foo') 时,后者也适用。如果htmlspecialchars 只有两个参数,则根本不要包含该参数,因为它是默认值(ENT_HTML401 是 0,记得吗?)。

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

另见下文,关于 ENT_SUBTITUTE 和 ENT_DISALLOWED。

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

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

您是否需要使用ENT_HTML401ENT_HTML5 或其他方式取决于您的页面的服务方式。如果您有 HTML5 页面 (&lt;!doctype html&gt;),请使用 ENT_HTML5。 XHTML 还是 XML?使用对应的ENT_XHTMLENT_XML1。如果没有 doctype 或普通的 HTML4,请使用 ENT_HTML401(省略时为默认值)。

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

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

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

【讨论】:

  • 哇,PHP 确实把这个搞砸了。不过答案很好!
  • 请注意,尽管文档不鼓励使用 ENT_IGNORE 来解决安全问题 (php.net/manual/en/function.htmlspecialchars.php),但其他 const 仅从 PHP 5.4.0 开始可用,而 ENT_IGNORE 已经在 PHP 5.3.0 中。
  • 可以像这样将 ENT_QUOTES 与 ENT_HTML5 结合起来:htmlspecialchars('&lt;""&gt;Test\'\'', ENT_QUOTES | ENT_HTML5)——这实际上意味着,翻译双引号和单引号,但是对于单引号,使用更好的 &amp;apos; 而不是数字 &amp;#039; .
猜你喜欢
  • 2010-09-13
  • 2011-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-20
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
相关资源
最近更新 更多