字符编码utf8到latin1,解释这两个字符

时间:2013-01-28 14:03:35

标签: php sql character-encoding

我有一个使用latin-1的数据库和一个utf-8的PHP应用程序。

我在数据库中有这样的字符串:

'Société'应该是Société

'â,11bn '应该是20亿欧元。

当我使用PHP的 ord()将错误字符打印到屏幕时,从数据库中返回的数据中打印195和226。

有人可以解释为什么会发生这种情况(为什么要像这样保存以及为什么要按原样读取字符)以及我是否可以撤消它。

2 个答案:

答案 0 :(得分:5)

为什么:

1)é是unicode 233(浏览器读取它) 转换为latin1 chars字节的é utf8字节为Ã ©。这就是数据库中出现这种情况的原因 Ã ©被识别为Ã,这是代码点195.因此,为什么你会看到它。

2)€是unicode 8364 转换为latin1字节字节的€utf8字节为â <82> ¬。这就是为什么它们在数据库中看起来像这样 â <82> ¬被识别为â,这是代码点226.这也是您看到这一点的原因。

这就是为什么你会看到来自ord()的值以及为什么字符以这种方式存储在latin-1数据库中的原因。

<强>反向:

要反转它,我们需要Latin-1个字节到UTF8个字节。

如果我们尝试一下:
â为226.将latin-1转换为utf8会产生â Ã为195.将latin-1转换为utf8会产生Ã

<强>问题:

问题是Latin-1的字符少于utf-8(很长一段时间) Latin1单字节流和UTF8多字节字符串流,因此utf8中的1个字符可以为latin1生成最多4个字符。
因此,UTF-8到Latin-1的转换会产生错误的字符 拉丁文1回到utf8是不可能的。

<强>解决方案:

如果您无法更改数据库的字符集,我可以建议在编写数据库之前在其字符实体中编码特殊字符(因此数据库可以保留为latin1和app作为utf8,因为两者都可以理解html实体)例如变音符号为&Auml;
可以使用PHP html_entity_decode()结合mb_detect_encoding()来检测和转换特定字符。

<强>参考文献:

ltf.ed.ac.uk 请参阅 utf8字节到latin1字节
http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=%C3%96&mode=char

答案 1 :(得分:0)

这些是UTF-8中的字符串,但显示为latin1。在UTF-8中é用两个字节编码,这就是当字符串被解释为latin1时你看到两个字符的原因。所以你要做的是将UTF-8数据存储在一个未声明为UTF-8的表中。您应该更改数据库*和连接**的编码,然后您将获得数据的一致表示

*)例如,请参阅此处:https://stackoverflow.com/a/6184788/664108案例2

SQL中的

**)SET NAMES 'utf8'