[英]PHP output encoding issues with UTF-8 strings from MySQL databases
我知道這個問題在這里一直以一種或另一種形式出現,但我對如何解決它有點不知所措。 我有一個運行 MySQL 的 PHP 網站,將一些擴展字符顯示為亂碼。 據我所知,從內容導入到在屏幕上顯示的每一步都被編碼為 UTF-8。 盡管如此,它仍然顯示出奇怪的編碼問題。 這是第一個測試示例(Natural Phënåm¥na,這是故意的),其中mb_detect_encoding
標識為 UTF-8,我只能使用utf8_decode
正確顯示:
no utf8_decode: Natural Phënåm¥na
utf8_decode: Natural Phënåm¥na
第二個例子,它甚至從來沒有正確地 utf8_decodes (應該是一個 ümlaut 和“排版師的引號”(故意添加的擴展字符,作為測試:
no utf8_decode: This pürson from “Vancouver, Canadaâ€
utf8_decode: This pürson from �??Vancouver, Canada�?�
我最初的想法是它被雙重編碼,但我認為這不是正在發生的事情。 當我在命令行上進行查詢時,一切都在 MySQL 中正確顯示。
以下是我調查過的所有事情的概述:
所以經過幾個小時的故障排除后,我有點不知所措。 一時興起,我什至嘗試將 HTML 標頭/元和 PHP 標頭設置為 ISO-8559-1,但這也不起作用。
我最后花了一段時間與 Amazon RDS 進行斗爭以設置正確的變量,但除此之外我沒有想法。
mysql> show variables like '%character%';
+--------------------------+-------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | utf8 |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/mysql-5.5.40.R1/share/charsets/ |
+--------------------------+-------------------------------------------+
所以我想知道,是否有我遺漏的步驟? 有什么明顯的? 提前致謝。
更新
這是我的 PHP 輸出腳本,為了進一步說明我提到的“輸出”:
<?php header("Content-type: text/html; charset=utf-8"); ?>
<html>
<header>
<meta charset="utf-8" />
<title>My test</title>
</header>
<body>
<?php
try {
$dbh = new PDO("mysql:host=localhost;dbname=database",
"user", "password", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
}
catch(PDOException $e) {
echo $e->getMessage();
}
$sth = $dbh->prepare("my select statement");
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo mb_detect_encoding($row['name']);
echo "<br>no utf8 decode: ". $row['name'] . "<br>\n";
echo "single utf8 decode: ". utf8_decode($row['name']) . "<br>\n";
echo "no utf8 decode: ". $row['description'] . "<br>\n";
echo "single utf8 decode: ". (utf8_decode($row['description'])) . "<br>\n";
}
?>
</body>
</html>
更新 #2我也嘗試過直接從 PHP echo 和直接的靜態 HTML 將這些相同的字符輸出到瀏覽器中,並且字符顯示得非常好。
echo "“test ü ö”<br>"; ?>
<p>“test ü ö”</p>
您不應更改所有character_set%
字段,僅更改受SET NAMES utf8;
影響的三個字段SET NAMES utf8;
.
不要使用 utf8_encode 或解碼。
您可能在存儲時搞砸了。
這似乎可以恢復字符,但這不是一個可行的解決方法:
CONVERT(CAST(CONVERT('pürson from “Vancouver, Canadaâ€' USING latin1)
AS BINARY)
USING utf8)
--> 'pürson from “Vancouver, Canada - spec',
為了弄清楚做了什么,請提供
SELECT col, HEX(col) FROM tbl WHERE ...
對於某些未正確渲染的單元格。
您提到在所有數據流中都是 utf-8 格式,除非它在屏幕上呈現。 我假設在瀏覽器上,而不是控制台上。 如果是這樣,請檢查 html 的<head>
標簽內是否有<meta charset="utf-8">
。 就像在 html5 樣板中一樣https://github.com/h5bp/html5-boilerplate/blob/master/dist/index.html
所以它看起來在 MySQL 級別上以某種方式在其中一些字段中對 UTF-8 字符進行了雙重編碼。 我終於能夠通過這篇很棒的博客文章走出 MySQL 字符集地獄來確定它。 不是 100% 清楚當它從 Python 發送時是否被“雙重編碼”,或者當它擊中 PHP API 時,但它是 90% 的答案,就在那里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.