这里有一些非常好的回答和尝试回答你的问题。虽然我不是编码大师,但我理解你想要在整个堆栈中使用纯UTF-8字符集的愿望。我一直在使用MySQL的utf8mb4编码来处理表格、字段和连接。
我的情况可以简化为“当数据来自HTML表单或电子邮件注册链接时,我只想让我的过滤器、验证器、业务逻辑和预设语句处理UTF-8”。因此,用我的简单方式开始了这个想法:
尝试检测编码:$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
如果无法检测到编码,则throw new RuntimeException
如果输入是UTF-8
,则继续。
否则,如果输入是ISO-8859-1
或者ASCII
a. 尝试转换为 UTF-8(等待,未完成)
b. 检测转换后值的编码
c. 如果报告的编码和转换后的值都是UTF-8
,则继续。
d. 否则,throw new RuntimeException
来自我的抽象类Sanitizer
![Sanitizer](https://istack.dev59.com/GY5Fh.webp)
private function isUTF8($encoding, $value)
{
return (($encoding === 'UTF-8') && (utf8_encode(utf8_decode($value)) === $value));
}
private function utf8tify(&$value)
{
$encodings = ['UTF-8', 'ISO-8859-1', 'ASCII'];
mb_internal_encoding('UTF-8');
mb_substitute_character(0xfffd);
mb_detect_order($encodings);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if (!$stringEncoding) {
$value = null;
throw new \RuntimeException("Unable to identify character encoding in sanitizer.");
}
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = mb_convert_encoding($value, 'UTF-8', $stringEncoding);
$stringEncoding = mb_detect_encoding($value, $encodings, true);
if ($this->isUTF8($stringEncoding, $value)) {
return;
} else {
$value = null;
throw new \RuntimeException("Unable to convert character encoding from ISO-8859-1, or ASCII, to UTF-8 in Sanitizer.");
}
}
return;
}
有人可能会认为我应该将编码问题与我的抽象Sanitizer
类分开,并简单地将一个Encoder
对象注入到Sanitizer
的具体子实例中。然而,我这种方法的主要问题在于,缺乏更多的知识,我只是拒绝我不想要的编码类型(我依赖于PHP mb_*函数)。没有进一步的研究,我无法知道这是否会对某些人口造成伤害或者是否会失去重要信息。因此,我需要学习更多。我发现了这篇文章。
每个程序员都绝对需要了解关于编码和字符集以处理文本的内容
此外,如果在我的电子邮件注册链接中添加了使用OpenSSL或mcrypt加密的数据,会发生什么?这是否会干扰解码?
Windows-1252有什么影响?安全方面的影响如何?在Sanitizer :: isUTF8中使用utf8_decode()和utf8_encode()是可疑的。人们指出了PHP mb_*函数的缺点。我从未花时间调查iconv,但如果它比mb_*函数更好,请告诉我。