如何在PHP和MySQL数据库中正确地进行字符编码?

4

可能是重复问题:
完全使用UTF-8编码

我已经尝试了很多方法,但仍然无法解决问题。

要在phpMyAdmin和HTML页面中显示相同的名称,需要什么条件?这是否可以实现?

编辑1:看起来这是一个mysql问题。为什么?因为由php生成的html页面将始终显示正确的字符。此时只有数据库显示不正确。

编辑2:澄清一下。按照以下代码片段和图像中显示的原始设置,

  1. 输入João并提交
  2. 数据库中显示João
  3. 重新加载后显示João

添加 mysqli_query ( $link, 'SET NAMES utf8' )

  1. 输入João并提交
  2. 数据库中显示João
  3. 重新加载后显示Jo�o

结束编辑2

在使用phpMyAdmin查看的mysql数据库中: database structure 数据库中的项目显示如下:(我已修改第一个João以正确显示在数据库中)

phpMyAdmin view of 2 entries of same name

在设置编码的HTML页面中,名称会显示为(顺序颠倒且修改后有黑色菱形)。

appearance in html page

编码: <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

我尝试将列排序更改为utf8_bin、utf8_general_ci、utf8_unicode_ci,但对两边都没有任何改变。还将文档(BBEdit)从UTF-8更改为UTF-8 (带BOM),ISO Latin 1和Windows Latin 1。其中一些创建了更多的黑色钻石,使问题变得更加严重。(在图像中设置为UTF-8) 我甚至尝试用编码等效物替换ã、é等。

简而言之,João输入到页面上(上面是内容类型),数据库中是João,在刷新时,João出现在html页面上。

寻找想法。谢谢。


也许你需要告诉你的数据库连接,接收到的数据是UTF-8编码的...这不会自动处理好...你选择了哪种连接方式?mysql(希望不是),mysqli还是pdo? - mineichen
@Pekka 很好。感谢您指出那个参考资料。 - David
@MarkusI。使用mysqli,phpMyAdmin报告“连接排序规则:utf8_general_ci”(也使用了utf-8_unicode_ci)。这是您所指的吗? - David
这似乎是一个显而易见的问题,但请确保您所关心的字符集已安装并启用于您的浏览器中。我曾经遇到过至少一种情况,即由于本地配置问题,一切都正常工作但显示错误。 - Joshua Kaiser
在设置连接之后,尝试添加$mysqli->set_charset("utf8"); - mineichen
4个回答

7
字符集问题通常非常难以解决。基本上,您需要确保以下所有内容都是真的:
  • DB连接使用UTF-8
  • DB表使用UTF-8
  • DB表中的各个列使用UTF-8
  • 数据实际上在数据库内以UTF-8编码正确存储(如果从错误源导入或更改了表或列排序规则,则通常不是这种情况)
  • 网页请求UTF-8
  • Apache提供UTF-8服务
这里有一个很好的教程,从头到尾处理这个列表:https://web.archive.org/web/20110303024445/http://www.bluebox.net/news/2009/07/mysql_encoding/
听起来你的问题具体是你有双编码(或三编码)字符,可能是由于改变字符集或使用错误字符集导入已编码数据造成的。上述教程中有整个修复部分。

1
对于解决问题的有条理方法,你给出了一个好答案。谢谢(需要一些时间来消化) - David
是的,这是一组复杂的相互关联的问题。几个月前,我花了四个小时帮助某人处理这个版本的问题。结果发现数据库中有双重编码字符,而在我的有限但痛苦的经验中,这种情况非常普遍。 - adrienne

1

请确保您的数据库连接也使用UTF-8编码。尝试在页面顶部添加以下行:

mysql_query("SET NAMES utf8");

哇,我正在处理这个问题。我已经将它包含在数据库条目脚本中(在输入之前),现在:数据库中是João,在HTML中是Jo�o,没有成功。 - David
在数据库会话中使用正确的字符集插入和检索数据,会发生什么? - symcbean
@symcbean,我认为你正在寻找刚才在你帖子上面的答案。添加coder1984建议的查询“reversed”了这个问题。请参见编辑2以获取摘要。 - David
不理解你的回复。在你对coder1984答案的第一个评论中,不清楚你从数据库检索到了哪个值 - 最初插入的值、修改后的值还是通过正确的连接类型使用php插入的值。 - symcbean

0

请确保您的HTML页面以及参与AJAX数据交换的脚本都使用适当的HTTP头进行服务,包括

Content-Type: text/html; charset=UTF-8

由于浏览器可能会忽略HTML端的编码设置


尤金,你可能在这里找到了一些东西。请求是:Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3,而响应是:Content-Type:text/html; charset=utf-8 老实说,我不确定这个字符集问题中谁在对谁做什么......请求有两个集合。(?) - David
页面显示Jo�o而不是João的响应头是什么? - Eugene
很好的问题。和我上面回答的一样。 - David
嗯...也许你之前的记录存储时使用了错误的编码方式?你可以尝试在phpMyAdmin中添加一些国际文本,以确保它是纯UTF-8格式,然后再查看HTML中呈现的内容。 - Eugene
1
检查 AJAX 请求/响应的标头可能也会有所帮助。 - Eugene

0

PHP默认不支持UTF8编码。请确保您使用mbstring函数而不是通常的内置字符串函数。


该脚本未使用任何字符串函数。事实上,字符串是通过ajax发送到数据库的。然后页面重新加载。这是一个由php生成的页面。 - David
在你的问题中加入一些代码会很好。 - Sammitch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接