根据PHP中的W3C规范化Unicode

fed*_*o-t 4 php unicode web-standards normalization unicode-normalization

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

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

…i??????????v??????????e???????????-????????????m??????????i??????????n????????…
Run Code Online (Sandbox Code Playgroud)

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

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

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

Juk*_*ela 5

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

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

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

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

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

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

  • 作为文本,它们应被视为等同.如果有操作也将它们视为八位字节,则它们不能.一个例子是,如果他们有一个数字签名 - 规范化会改变它,使它不再是签名的.这就是XML签名作为实际签名的一部分进行规范化步骤的原因,因此它只会是签名的NFC.当输出为HTML时,它将作为文本输出,这是无关紧要的,因此它应该仍然是NFC,但您可能有理由保留发送的表单. (2认同)