MySQL直插德文字符输出到HTML页面显示乱码如何解决
问题描述
已查阅现有相关解决方案未找到对应解法,问题场景如下:
MySQL中存储的数据查询后展示到HTML网页时德文字符无法正常显示,直接插入数据的SQL语句如下:
INSERT INTO `extra_ingredients` (`extra_Ingredient_Serial`, `extra_Ingredient_Category`, `extra_Ingredient_Sub`, `extra_Ingredient_Name`) VALUES (NULL, 'Pizza', '1', 'Sahnesauce'), (NULL, 'Pizza', '1', 'Dönerfleisch'), (NULL, 'Pizza', '1', 'Schafskäse');
数据库表内数据显示正常:
查询输出到HTML页面时显示异常:
已做的排查尝试:
- HTML页面已配置使用UTF-8编码
- 数据库排序规则试过
utf8mb4_german2_ci、utf8_german2_ci、utf8_unicode_ci - 数据通过SQL语句直接批量插入,未经过HTML表单录入
补充现象:通过HTML表单录入数据时,网页端输出显示正常,但MySQL表内存储内容异常:录入soße时表内存储为soße,查询输出到网页又能正常显示为soße。需要保留SQL批量插入的方式,不希望通过表单逐行录入。
问题根因
这是典型的全链路字符集不统一问题,只设置HTML编码和库表排序规则,没有配置MySQL连接层的字符集,导致出现双重编码现象:
表单提交时,前端发送UTF-8编码的字节流,MySQL连接层默认按latin1编码解析,错误转码后存入表中(所以看到表里是soße);查询时连接层又把存错的内容反向转成latin1输出,前端按UTF-8解析刚好歪打正着显示正确。而直接通过SQL插入的数据是按正确UTF-8编码存入的,查询时被连接层错误转码,就会在网页端显示乱码。
解决步骤
- 统一库、表、字段字符集为
utf8mb4(不要使用MySQL内置的3字节utf8,存在字符兼容缺陷),排序规则保留utf8mb4_german2_ci即可,执行以下SQL修正:
-- 修改数据库默认字符集 ALTER DATABASE 你的数据库名 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_german2_ci; -- 修改目标表及所有字段字符集 ALTER TABLE extra_ingredients CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci;
- 配置MySQL连接层字符集,这是最核心的遗漏步骤:在后端程序建立MySQL连接后,第一时间将连接字符集设置为
utf8mb4,不同连接方式的参考写法:- PDO连接:在DSN中添加charset参数,示例:
$pdo = new PDO('mysql:host=localhost;dbname=你的库名;charset=utf8mb4', '数据库用户名', '数据库密码'); - MySQLi连接:连接后执行
$mysqli->set_charset('utf8mb4');,或直接执行SQL语句SET NAMES utf8mb4;
- PDO连接:在DSN中添加charset参数,示例:
- 清空之前插入的乱码数据,重新执行批量插入的SQL语句即可。
- 核对HTML页面meta标签配置正确:
<meta charset="UTF-8">,已完成该步可直接跳过。
验证标准
全部配置完成后满足以下三点即为修复成功:
- 直接通过SQL插入带ö、ä、ü、ß等德文字符的数据,数据库表内直接查看显示正常,无乱码
- 数据库查询结果输出到HTML页面时,德文字符显示正常
- HTML表单提交的德文字符存入数据库时不再出现
soße这类转码错误,表内存储和前端显示完全一致
不要依赖双重编码带来的“歪打正着”的正常显示,这种状态下数据导出、跨服务调用、更换客户端时都会出现大面积乱码,必须保证从数据库连接、库表存储到前端输出的全链路字符集统一为
utf8mb4才能彻底解决问题。
内容的提问来源于stack exchange,提问作者Amir Ahmad
相关产品推荐
相关产品推荐

