首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP 寫入 MySQL 中文報錯「Data too long」真凶:字符集不匹配而非長度溢出

     編輯:MySQL 資料庫相關知識

錯誤現象

Data too long for column 'xxx' at row 1

乍看像欄位長度不夠,實際卻是**字符集編碼不匹配**導致的位元組長度暴增。

根因剖析

  • 建庫時選了 **非 latin1** 編碼(如 UTF-8/GBK)
  • MySQL 預設連線字符集為 **latin1**
  • PHP 送 UTF-8/GBK 位元組流,MySQL 按 latin1 解讀 → 1 個中文字符被誤判為 2-3 個 latin1 字符 → 位元組長度翻倍/三倍 → 超過欄位定義長度

兩種解決路徑

方案 A:連線層指定字符集(推薦,不改庫配置)

// PHP mysql 擴展(已棄用)
mysql_query("SET NAMES 'gbk'");  // 或 utf8

// PHP mysqli
$mysqli->set_charset('gbk');  // 或 utf8

// PDO
$pdo = new PDO('mysql:host=...;charset=gbk', 'user', 'pass');

⚠️ 若庫建表時已用 UTF-8,這裡必須設 utf8;若用 GBK,設 gbk。**連線字符集必須與表欄位字符集一致**。

方案 B:建庫時堅持用 latin1(不推薦現代專案)

  • 建庫/建表不指定字符集 → 繼承 latin1
  • 連線層無需設定,預設 latin1 互通
  • 缺點:無法存儲多語言、Emoji,排序規則異常,**強烈不建議新專案使用**

驗證檢查清單

  1. SHOW CREATE TABLE tblname → 確認欄位 CHARSET
  2. SHOW VARIABLES LIKE 'character_set_%' → 確認 client/connection/results
  3. PHP 端 mysqli_character_set_name($link) / PDO::getAttribute(PDO::ATTR_SERVER_VERSION) 確認連線字符集
  4. 寫入測試:INSERT ... VALUES ('測試') → SELECT HEX(col), CHAR_LENGTH(col), LENGTH(col) 對照

現代最佳實踐:全鏈路 UTF-8MB4

# my.cnf
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# 建表
CREATE TABLE t (c VARCHAR(100)) CHARSET=utf8mb4;

# PHP
$mysqli->set_charset('utf8mb4');
// 或 PDO DSN charset=utf8mb4
「Data too long」90% 是字符集假象。統一全鏈路 utf8mb4,徹底告別編碼地獄。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved