首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

解決 PHP 連接 MySQL 4.1+ 亂碼:SET NAMES utf8 原理與實踐

     編輯:MySQL 綜合教學

亂碼根因:連接層字符集不匹配

MySQL 4.1 引入四層字符集體系:

  1. Server(服務器級)
  2. Database(庫級)
  3. Table(表級)
  4. Connection(連接層) —— 最關鍵、最常被忽略

PHP 腳本發送 SQL 時,若連接層仍為 latin1,中文會被錯誤編碼寫入,讀出時再按 latin1 解碼,產生亂碼。

查看當前字符集狀態

SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

關鍵變量:

  • character_set_client:客戶端發送數據的編碼
  • character_set_connection:連接層處理編碼
  • character_set_results:結果集返回編碼

一鍵修復:SET NAMES utf8

-- 相當於執行以下三條
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;

PHP 中最佳實踐

<?php
$mysqli = new mysqli('localhost', 'root', 'pass', 'db');
if ($mysqli->connect_errno) die('Connect Error: ' . $mysqli->connect_error);

// 關鍵:建立連接後立即設置
$mysqli->set_charset('utf8mb4');  // 推薦 utf8mb4 支援 Emoji
// 或 $mysqli->query("SET NAMES utf8mb4");

// PDO 方式
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'root', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>

表/庫級字符集設置(治本)

-- 建庫指定
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 建表指定
CREATE TABLE t (c VARCHAR(100)) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 修改現有表(需轉換數據)
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

常見坑點

現象原因解決
存入正常,讀出亂碼character_set_results 錯誤SET NAMES / set_charset
讀出正常,存入亂碼character_set_client 錯誤同上
中文截斷/報錯字段長度按字節計算,utf8mb4 佔 4 字節擴大字段長度或用 TEXT
排序不符合拼音校對規則非中文COLLATE utf8mb4_unicode_ci

總結

  1. 庫/表統一 utf8mb4 + utf8mb4_unicode_ci。
  2. 應用層連接建立後第一條語句執行 SET NAMES utf8mb4(或 set_charset)。
  3. PHP 5.3.6+ / PDO 支援 DSN 中 charset=utf8mb4 參數,最簡潔。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved