MySQL 在 UTF-8 PHP 文件中输出西方编码

Posted

技术标签:

【中文标题】MySQL 在 UTF-8 PHP 文件中输出西方编码【英文标题】:MySQL outputs Western encoding in UTF-8 PHP file 【发布时间】:2012-09-26 02:46:10 【问题描述】:

我有以下问题:在一个非常简单的 php-mysqli 查询上:

if ( $result = $mysqli->query( $sqlquery ) )

    $res = $result->fetch_all();
    $result->close();

尽管数据库、表和列在utf8_general_ci 排序规则中,但我得到的字符串被错误地编码为西方编码字符串。 php 脚本本身是 utf-8 编码的,并且脚本的 mysql-less 部分得到正确的编码。所以说echo "ő" 工作得很好,但是上一个示例中的echo $res[0] 在以正确的UTF-8 编码查看文件时输出EF BF BD 字符。如果我手动将浏览器的编码切换为西方,则 mysqli 来源的字符串得到很好的解码,除了非西方字符被替换为“?”。

更奇怪的是,在我的开发环境中没有发生这种情况,而在我的网络服务器上却发生了。开发环境是 LAMP 栈(The Uniform Server),而 webserver 使用 nginx

在这种情况下,我使用phpMyAdmin将数据输入到数据库中,并且在phpmyadmin中它可以完美显示。 phpMyAdmin 的排序规则也是 utf-8。我相信问题一定出在此处,就像在同一个网络服务器上一样,对于我通过 php(使用 POST)输入数据的其他站点,不会发生同样的问题。在这种情况下,数据在输入和查看时都可以正确看到(我的意思是在 php 生成的网页中),但特殊字符在 phpMyAdmin 中不正确。

你能帮我从哪里开始调试吗?是否连接到 phpmysqlnginxphpMyAdmin

【问题讨论】:

虽然不熟悉mysqli:PHP头是否告诉浏览器正确的编码? 【参考方案1】:

使用 mysqli::set_charset 函数。

$mysqli->set_charset('utf8'); //returns false if the encoding was not valid... won't happen

http://php.net/manual/en/mysqli.set-charset.php

我已经有一段时间没有使用 mysqli,但如果情况相同,默认情况下连接使用拉丁瑞典编码 (ISO 8859 1)。

我会认为你的页面已经在使用 utf8 编码:

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

&lt;head&gt; 标签内。

如果你已经有拉丁瑞典语编码的字符串,你可以使用 mk_convert_encoding:

http://php.net/manual/en/function.mb-convert-encoding.php

$fixedStr = mb_convert_encoding($wrongStr, 'UTF-8', 'ISO-8859-1');

iconv 做了非常相似的事情:说实话,我不知道有什么区别,但这里是函数参考的链接: http://php.net/manual/en/function.iconv.php

我刚刚意识到您可能有一些 utf8 字符串和拉丁瑞典语的其他字符串。您可以为此使用 mb_detect_encoding:http://php.net/manual/en/function.mb-detect-encoding.php

如果已安装,您还可以转储数据库并使用 iconv(cmd 行):

iconv -f latain -t utf-8 < currentdb.sql > fixeddb.sql

【讨论】:

感谢它的工作!你能指点一下如何在仍然使用原始编码的同时转换从 PHP 填充的数据库内容吗?【参考方案2】:

在您连接后使用mysqli_set_charset 将客户端编码更改为UTF-8:

$mysqli->set_charset("utf8");

客户端编码是 MySql 期望您输入的内容(例如,当您将用户提供的文本插入搜索查询时)以及它为您提供的结果(因此它必须匹配您的输出编码才能@ 987654324@ 正确显示内容)。

您需要让它与您的网页的编码相匹配以解决上述两种情况 PHP 源文件的编码(以便正确解释查询的硬编码部分) .

更新:如何将使用 latin-1 插入的数据转换为 utf-8

对于已经使用错误的连接编码插入的数据,有一个方便的解决方案来解决这个问题。对于包含此类数据的每一列,您需要执行以下操作:

ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET latin1;
ALTER TABLE table_name MODIFY column_name BLOB;
ALTER TABLE table_name MODIFY column_name existing_column_type CHARACTER SET utf8;

每次都应将占位符 table_namecolumn_nameexisting_column_type 替换为数据库中的正确值。

这是做什么的

    告诉 MySql 它需要在 latin1 的那一列中存储数据。此字符集仅包含 utf8 的一小部分,因此通常此转换涉及数据丢失,但在此特定情况下,数据在输入时已被解释为 latin1,因此不会有副作用。但是,MySql 会在内部转换数据的字节表示以匹配最初从 PHP 发送的内容。 将列转换为没有相关编码信息的二进制类型 (BLOB)。此时,该列将包含作为正确 utf8 字符串的原始字节。 将列转换为之前的字符类型,告诉 MySql 原始字节应该被认为是 utf8 编码。

警告:如果有问题的列包含错误插入的数据,则只能使用这种不分青红皂白的方法。任何已正确插入的数据将在第一次出现任何非 ASCII 字符时被截断!

因此,最好在 PHP 端修复生效之前立即执行此操作。

【讨论】:

感谢它的工作!你能指点一下如何在仍然使用原始编码的同时转换从 PHP 填充的数据库内容吗? 非常感谢,很高兴看到它可以在不使用 PHP 的情况下进行转换!

以上是关于MySQL 在 UTF-8 PHP 文件中输出西方编码的主要内容,如果未能解决你的问题,请参考以下文章

如何在php中输出utf-8文本

正确的输出,网站是 utf-8,mysql 是 latin1_swedish_ci

mysql显示汉字

php连mysql用 utf-8编码乱码怎么办

如何让 MySQL 返回 UTF-8?

使用 PHP 从 MySQL 结果输出复杂的 JSON