PHP连接MySQL需四层统一UTF-8:①连接时强制设utf8mb4(mysqli用set_charset,PDO在DSN加charset=utf8mb4);②表与字段字符集必须为utf8mb4;③PHP文件存为UTF-8无BOM,输出HTML前设header及meta;④JSON用JSON_UNESCAPED_UNICODE。

PHP连接MySQL时怎么设置UTF-8编码
不设编码,mysqli 或 PDO 默认可能用 latin1,哪怕网页和数据库都声明了 UTF-8,插入中文照样变问号或乱码。关键不是“加编码”,而是**在连接建立的第一时间就强制指定字符集**。
-
mysqli连接后必须立刻调用set_charset('utf8mb4')(注意是utf8mb4,不是utf8) -
PDO要在 DSN 中加入;charset=utf8mb4,例如:mysql:host=localhost;dbname=test;charset=utf8mb4 - 仅在 SQL 里写
SET NAMES utf8mb4是靠不住的——它只影响当前会话,且容易被中间件、连接池覆盖
MySQL表和字段的编码必须是utf8mb4
即使 PHP 连接对了,如果表结构本身不是 utf8mb4,插入依然失败。常见错误是只改了数据库默认字符集,却漏掉具体表和字段。
- 建表时显式指定:
CREATE TABLE t (name VARCHAR(255)) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - 修改已有表:
ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 检查是否生效:
SHOW CREATE TABLE t;看CHARSET和COLLATE字段 -
utf8在 MySQL 里是阉割版(最多3字节),存 emoji 或某些生僻汉字会截断——必须用utf8mb4
PHP脚本自身和HTML输出也要匹配
PHP文件保存编码、HTTP头、HTML meta 标签三者不一致,前端显示仍会乱码,尤其 AJAX 返回 JSON 时容易忽略。
- PHP 文件用 UTF-8 无 BOM 格式保存(编辑器里确认,别用 Windows 记事本)
- 输出 HTML 前加:
header('Content-Type: text/html; charset=utf-8'); - HTML 中写:
(不要写成utf-8小写,部分老浏览器敏感) - JSON 输出用
json_encode($data, JSON_UNESCAPED_UNICODE),否则中文变 \uXXXX
为什么用 utf8mb4 而不是 utf8
MySQL 的 utf8 不是真正的 UTF-8,它只支持最多 3 字节的字符;而标准 UTF-8(如 emoji、古汉字、数学符号)需要 4 字节。utf8mb4 才是完整实现。从 MySQL 5.5.3 起就支持,现在已是事实标准。
立即学习“PHP免费学习笔记(深入)”;
- 配置文件
my.cnf中设全局:[client] default-character-set = utf8mb4[mysqld] character-set-server = utf8mb4collation-server = utf8mb4_unicode_ci - 重启 MySQL 后执行
SHOW VARIABLES LIKE 'character_set%';确认所有值都是utf8mb4 - 旧项目迁移时,
ALTER TABLE可能失败——先确保字段长度足够(VARCHAR(255)在utf8mb4下实际占用更多字节),必要时扩大字段
SET NAMES 更有效。











