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 中不正确。
你能帮我从哪里开始调试吗?是否连接到 php 或 mysql 或 nginx 或 phpMyAdmin?
【问题讨论】:
虽然不熟悉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"/>
在<head>
标签内。
如果你已经有拉丁瑞典语编码的字符串,你可以使用 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_name
、column_name
和 existing_column_type
替换为数据库中的正确值。
这是做什么的
-
告诉 MySql 它需要在 latin1 的那一列中存储数据。此字符集仅包含 utf8 的一小部分,因此通常此转换涉及数据丢失,但在此特定情况下,数据在输入时已被解释为 latin1,因此不会有副作用。但是,MySql 会在内部转换数据的字节表示以匹配最初从 PHP 发送的内容。
将列转换为没有相关编码信息的二进制类型 (
BLOB
)。此时,该列将包含作为正确 utf8 字符串的原始字节。
将列转换为之前的字符类型,告诉 MySql 原始字节应该被认为是 utf8 编码。
警告:如果有问题的列包含仅错误插入的数据,则只能使用这种不分青红皂白的方法。任何已正确插入的数据将在第一次出现任何非 ASCII 字符时被截断!
因此,最好在 PHP 端修复生效之前立即执行此操作。
【讨论】:
感谢它的工作!你能指点一下如何在仍然使用原始编码的同时转换从 PHP 填充的数据库内容吗? 非常感谢,很高兴看到它可以在不使用 PHP 的情况下进行转换!以上是关于MySQL 在 UTF-8 PHP 文件中输出西方编码的主要内容,如果未能解决你的问题,请参考以下文章