首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 连接 MySQL 出现 UTF-8 乱码的六大解决方案

     編輯:PHP 相關知識

乱码根因

MySQL 连接、表存储、PHP 内部编码、页面输出编码**任一环节不一致**即会导致乱码。核心链路:

PHP 脚本 (内部编码) → MySQL 连接 (字符集) → 表/列 (字符集) → 页面输出 (HTTP Header/Content-Type)

六大解决方案(按生效层级排序)

1. MySQL 服务端配置 (my.cnf / my.ini) —— 根治

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
skip-character-set-client-handshake = 1  # 强制忽略客户端声明的字符集

重启 MySQL 生效。推荐 utf8mb4(完整支持 Emoji),而非旧 utf8(仅 3 字节)。

2. PHP 连接时显式设置字符集 —— 必做

PDO (推荐):

$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
$pdo = new PDO($dsn, $user, $pass, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => false,
]);

mysqli:

$mysqli = new mysqli('localhost', $user, $pass, 'test');
$mysqli->set_charset('utf8mb4'); // 必须在查询前调用

旧 mysql_* 函数 (已移除):mysql_set_charset('utf8mb4', $link);

3. 建表/建库指定字符集

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

已有表转换:ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

4. PHP 内部编码统一

<?php
// 脚本开头设置
mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');
mb_http_input('UTF-8');
mb_regex_encoding('UTF-8');
// 或 php.ini 全局生效
// mbstring.internal_encoding = UTF-8
// mbstring.http_output = UTF-8
?>

5. 页面输出声明 UTF-8

<?php
// 必须在任何输出前
header('Content-Type: text/html; charset=utf-8');
?>
<meta charset="utf-8"> <!-- HTML5 简写 -->

6. phpMyAdmin 导入导出兼容

  • config.inc.php:$cfg['DefaultCharset'] = 'utf-8';
  • 导出时**取消勾选**“二进制字段使用十六进制显示”,避免 0xE4B8AD 形式导入后变乱码。

排查清单(按顺序验证)

  1. 数据库/表/列字符集是否为 utf8mb4?SHOW CREATE TABLE users;
  2. PHP 连接是否执行了 SET NAMES utf8mb4 / set_charset?
  3. PHP mb_internal_encoding 是否为 UTF-8?
  4. HTTP 响应头 Content-Type 是否含 charset=utf-8?
  5. HTML <meta charset="utf-8"> 是否存在?
  6. 源文件编码是否为 UTF-8 无 BOM?(编辑器右下角确认)

常见误区

误区真相
用 SET NAMES utf8 就够utf8 是 MySQL 别名,实际仅 3 字节,存 Emoji 会截断报错。必须用 utf8mb4。
phpMyAdmin 设置了 DefaultCharset 就行phpMyAdmin 只是管理工具,不影响应用程序连接字符集。
数据库默认 latin1,改表字符集就好需 CONVERT TO CHARACTER SET 重写数据,单纯 ALTER ... CHARSET 只改默认值,现有数据不转换。

一劳永逸最佳实践

  1. MySQL 服务端 character-set-server = utf8mb4 + skip-character-set-client-handshake。
  2. 所有建库建表显式 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci。
  3. PHP 统一用 PDO + DSN charset=utf8mb4。
  4. 入口文件统一 header('Content-Type: ...; charset=utf-8') + mb_internal_encoding('UTF-8')。
  5. 源码文件统一 UTF-8 无 BOM,Git 提交强制 .gitattributes * text=auto eol=lf。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved