根据PHP中的W3C规范化Unicode

时间:2012-01-07 01:52:39

标签: php unicode normalization web-standards unicode-normalization

W3C validator验证我网站的HTML代码时,我收到了以下警告:

Line 157, Column 220: Text run is not in Unicode Normalization Form C.

…i͈̭̋ͥ̂̿̄̋̆ͣv̜̺̋̽͛̉͐̀͌̚e͖̼̱ͣ̓ͫ͆̍̄̍͘-̩̬̰̮̯͇̯͆̌ͨ́͌ṁ̸͖̹͎̱̙̱͟͡i̷̡͌͂͏̘̭̥̯̟n̏͐͌̑̄̃͘͞…

我正在PHP 5.3.x中开发它,所以我可以使用Normalizer类。

因此,为了解决这个问题,我应该在显示用户做出的任何输入时使用Normalizer::normalize($output)(例如注释),还是应该在将Normalizer::normalize($input)用于任何用户输入之前使用{{1}}数据库?

tl; dr:我应该在将用户输入存储在数据库中之前使用Unicode normalization还是只在显示时显示?

2 个答案:

答案 0 :(得分:5)

由您决定,根据应用程序的目的和性质,您是在读取用户输入时应用规范化,还是将其存储到数据库中,或者在编写时,或者根本不应该。总结问题评论中提到的长线程,也可以在http://validator.w3.org/feedback.html的官方列表档案中找到

  • 警告信息来自实验性的“HTML5验证”(除了一些正式的测试之外,它实际上是一个linter,应用主观规则)。
  • 该消息不是基于HTML5草案中的任何要求,而是基于对可能导致某些软件出现问题的意见。
  • 最初提出的意见“HTML5验证”会发出错误消息,现在是一个警告。

将非标准化数据作为用户输入肯定是可能的,尽管不常见。这不依赖于浏览器执行的规范化(它们不会做这些事情,尽管可能在将来可能会这样做),而是依赖于输入方法和习惯。例如,键入字母ü(u umlaut或u with diaeresis)的方法往往会产生预组合形式的字符,如规范化。人们可以将其生成为非标准化的,以分解的形式生成,如字母u,然后组合分离,但他们通常没有理由这样做,大多数人甚至不知道如何做到这一点。 / p>

如果您在软件中进行字符串比较,它们可能会或可能不会(取决于使用的比较例程)处理,例如预组合ü等于分解的表示。简单的实现将它们视为不同的,因为它们在简单的字符级别(Unicode代码点)上肯定是不同的。

最近在写作阶段进行标准化的一个原因是预组合字符通常会更可靠地显示。要呈现标准化的ü,程序只需从字体中获取字形。为了呈现一个分解的ü,一个程序必须要么将它识别为规范化的ü,或者用正确放置在它上面的分音符号写出字母u,并适当注意字形的图形属性,并且许多程序失败在这。

另一方面,在极少数情况下,接收到非标准化数据作为用户输入,用户可能有理由产生它。他可能认为归一化ü和非归一化ü是不同的,需要对其进行处理。

答案 1 :(得分:1)

严格地说,网络角色模型的规则不仅仅是应该归一化为NFC,而且在包含来自其他机制的文本的任何技术之后的形式之前和形式都应该在NFC中。示例包括XML包含,字符引用和实体引用。例如,ä不适合角色模型,因为它在NFC中扩展,角色参考将其转换为a,然后是组合的深度,而不是NFC。在实践中大多避免这种情况非常容易,但值得注意。

U + 0338有一个有趣的案例。 >后跟U + 0338标准化为<生成。不应该在元素名称的开头或作为元素中的第一个字符的原因应该是明确的。

作为一项规则,在任何情况下让一段文本以组合字符开头是没有意义的,但是这个特定的例子允许整个文档被修改(即使你没有规范化,因为其他的东西可)。

如果您只关注文本文本(例如,数字签名不感兴趣),那么对输入进行规范化可以简化您所做的其余工作,包括您对文本的内部使用(例如搜索),可能是要走的路。

有关详情,请参阅http://www.w3.org/TR/charmod-norm/