php讀取mysql數(shù)據(jù)出現(xiàn)亂碼的主要原因是連接編碼設(shè)置不正確,解決方法包括:1. 設(shè)置數(shù)據(jù)庫和表的默認(rèn)字符集為utf8mb4;2. 在php中使用mysqli或pdo連接時(shí)明確指定編碼為utf8mb4;3. 檢查網(wǎng)頁輸出和html頭信息,確保瀏覽器以u(píng)tf-8解析頁面;4. 排查數(shù)據(jù)庫、表、字段字符集是否統(tǒng)一,連接是否正確設(shè)置,輸出頭是否正確,以及是否存在已錯(cuò)誤編碼的數(shù)據(jù)。只要確保整個(gè)鏈路字符集一致,即可避免大多數(shù)亂碼問題。
PHP讀取MySQL數(shù)據(jù)出現(xiàn)亂碼,大多數(shù)情況下是連接編碼設(shè)置不正確導(dǎo)致的。解決這個(gè)問題的核心在于確保整個(gè)數(shù)據(jù)傳輸鏈路中的字符集一致,包括數(shù)據(jù)庫、表、字段、連接以及php腳本本身的編碼。
以下是一些常見且有效的設(shè)置方法,幫你搞定亂碼問題。
設(shè)置數(shù)據(jù)庫和表的默認(rèn)字符集
在MySQL中,如果數(shù)據(jù)庫或表的默認(rèn)字符集不是utf8mb4(推薦),就可能導(dǎo)致存儲(chǔ)或讀取時(shí)出現(xiàn)亂碼。
立即學(xué)習(xí)“PHP免費(fèi)學(xué)習(xí)筆記(深入)”;
- 創(chuàng)建數(shù)據(jù)庫時(shí)指定字符集:
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 修改已有數(shù)據(jù)庫的字符集:
ALTER DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
- 查看數(shù)據(jù)庫當(dāng)前字符集:
SHOW CREATE DATABASE mydb;
同樣地,對(duì)于數(shù)據(jù)表也應(yīng)做類似的設(shè)置:
ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
在PHP中設(shè)置連接編碼
即使數(shù)據(jù)庫和表設(shè)置了正確的字符集,如果PHP連接MySQL時(shí)不指定編碼,仍然可能出現(xiàn)亂碼。
使用 mysqli 時(shí)設(shè)置編碼:
$mysqli = new mysqli("localhost", "user", "password", "mydb"); $mysqli->set_charset("utf8mb4");
使用 PDO 時(shí)設(shè)置編碼:
$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4'; $opt = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ]; $pdo = new PDO($dsn, 'user', 'password', $opt);
注意:不要使用 utf8,MySQL 的 utf8 只支持最多 3 字節(jié)的字符,而 utf8mb4 才能完整支持 emoji 等 4 字節(jié)字符。
檢查網(wǎng)頁輸出和HTML頭信息
有時(shí)候,頁面顯示亂碼是因?yàn)?a href="http://www.babyishan.com/tag/%e6%b5%8f%e8%a7%88%e5%99%a8">瀏覽器沒有正確識(shí)別編碼格式。即使后端數(shù)據(jù)沒問題,前端展示也可能出錯(cuò)。
- 在 PHP 中添加頭部設(shè)置:
header('Content-Type: text/html; charset=utf-8');
- HTML 頁面中加上 meta 標(biāo)簽:
<meta charset="UTF-8">
這樣可以確保瀏覽器以 UTF-8 編碼解析頁面內(nèi)容。
常見排查點(diǎn)總結(jié)
如果你已經(jīng)做了上述設(shè)置但仍有亂碼,可以從以下幾個(gè)方面再檢查一遍:
- 數(shù)據(jù)庫、表、字段的實(shí)際字符集是否統(tǒng)一為 utf8mb4
- PHP連接MySQL時(shí)是否調(diào)用了 set_charset(“utf8mb4”) 或在 DSN 中指定了 charset=utf8mb4
- 輸出內(nèi)容前是否設(shè)置了正確的 http 頭 Content-Type
- 數(shù)據(jù)本身是否已經(jīng)被錯(cuò)誤編碼寫入(比如之前存的是 GBK 編碼的內(nèi)容)
有些時(shí)候,舊數(shù)據(jù)可能已經(jīng)存在亂碼,這時(shí)候需要先修復(fù)原有數(shù)據(jù),再重新保存。
基本上就這些設(shè)置,只要每一步都確認(rèn)到位,就能避免大部分亂碼問題。