PHP卷曲引用字符编码问题

Ken*_*ong 4 php mysql encoding utf-8

我知道在不同的字符集之间存在一个古老的字符编码问题,但我仍然坚持与Window的"曲线引号"相关的问题.

我们有一个客户端喜欢将数据复制并粘贴到文本字段中,然后将其发布到我们的应用程序中.该数据通常会包含卷曲引号.我曾经使用以下方法将它们转换为正常的对应物:

function convert_smart_quotes($string)  { 

$badwordchars=array("\xe2\x80\x98", "\xe2\x80\x99", "\xe2\x80\x9c", "\xe2\x80\x9d", "\xe2\x80\x93", "\xe2\x80\x94", "\xe2\x80\xa6");

$fixedwordchars=array("'", "'", '"', '"', '-', '--', '...');

return str_replace($badwordchars,$fixedwordchars,$string); 

}
Run Code Online (Sandbox Code Playgroud)

这个工作好几个月了.然后经过一些更改(我们切换服务器,对系统进行更新,升级PHP等等),我们了解到它不再起作用了.所以,我看看,我了解到"卷曲引号"都变成了不同的字符.在这种情况下,他们将变成以下内容:

"=¡

"=¡É

'=¡

'=¡

这些字符在保存在数据库中时显示为被诅咒的"黑钻石问号符号".mySQL数据库位于latin1_swedish_ci中,接收消息的应用程序也是如此.所以,虽然我知道utf-8更好,但它必须保留在latin1_swedish_ci或ISO-8859-1中,否则我们将不得不重建所有东西......这是不可能的.

我的网页和表单都在utf-8中发布.如果我将其更改为ISO-8859-1,引号将成为问号.

我已经尝试在字符串中搜索"¡È"或"¡É"的出现并用正常的引号替换它们,但我无法让它工作.我通过在上面的函数中添加以下内容来完成它:

$string = str_replace("xa1\xc8", '"', $string);
$string = str_replace("xa1\xc9", '"', $string);
$string = str_replace("xa1\xc6", "'", $string);
$string = str_replace("xa1\xc7", "'", $string);
Run Code Online (Sandbox Code Playgroud)

我已经被困在这几个小时了,并且无法在网上找到任何真正的帮助.你可以想象,googleing"¡É"并没有带来非常具体的反应.

任何指导表示赞赏!

sjy*_*sjy 8

您的问题是您接受用户的UTF-8输入,然后将其插入数据库,就像它是Latin1(ISO-8859-1)一样.(请注意,这latin1_swedish_ci不是编码而是排序规则(对于Latin1).请参阅此问题的差异.为了解决您的字符编码问题,排序并不重要.)

您应该使用强大的方法将UTF-8字符串转换为Latin1,而不是手动识别重要的UTF-8序列并替换它们iconv.

请注意,这是一个有损转换:Latin1中不存在某些UTF-8字符(如引号).你可以选择忽略这些字符(用空字符串替换它们,或者用其他东西替换它们),或者你可以选择音译它们(用等价的替代它们,就像"卷曲的引用一样......但是你做什么如果有人提出?你的表格?

iconv 将尝试在可能的地方进行音译:

// convert from utf8 to latin1, approximating out of range characters
// by the closest latin1 alternative where possible (//TRANSLIT)
$latinString = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $utf8String);
Run Code Online (Sandbox Code Playgroud)

(您也可以将其配置为忽略所有超出范围的字符 - 有关详细信息,请参阅iconv文档.)

如果您不想添加新库,PHP还附带了以下utf_decode功能:

$latinString = utf_decode($utf8String);
Run Code Online (Sandbox Code Playgroud)

但是,PHP并没有真正考虑到多个字符编码的设计,所以我更喜欢远离处理编码的(有时是错误的)标准库函数.

您还应该考虑完全阅读绝对最低每个软件开发人员,必须知道关于Unicode和字符集(没有借口!).