在使用 MySQL 数据库存储用户输入内容时,尤其是像评论、昵称、聊天记录这样的文本字段,我们经常会遇到一个问题:当用户输入了 Emoji 表情或某些特殊的 Unicode 符号时,保存到数据库会失败,或者即使保存成功,取出来显示时却是乱码或问号(?)。
这是因为 MySQL 数据库默认的字符集(如 utf8)并不能完全支持 4 字节的 Unicode 字符(包括大部分 Emoji)。要解决这个问题,除了数据库层面的配置外,PHP 代码中也要确保客户端连接的字符集是设置正确的。本文将介绍如何使用 mysqli::get_charset 函数检查并确保连接字符集正确,以解决 Unicode 表情无法存储的问题。
MySQL 的 utf8 编码实际上只支持最多 3 个字节的字符,而 Emoji 和部分 Unicode 字符需要 4 个字节,因此必须使用 utf8mb4。如果服务器端(数据库表、字段、连接)没设置好 utf8mb4,这些字符要么插入失败,要么被截断、替换成问号。
通常,我们需要做到三点:
数据库和表的字符集设置为 utf8mb4。
数据库连接时指定 utf8mb4。
确认 PHP 代码中使用的字符集正确。
PHP 的 mysqli 类提供了 get_charset 方法,可以用来获取当前连接的字符集信息。通过这个函数,我们可以在代码中检查当前连接是否已经使用 utf8mb4,并在不匹配时进行调整。
示例代码如下:
<?php
// 数据库连接信息
$mysqli = new mysqli('localhost', 'username', 'password', 'database');
// 检查连接是否成功
if ($mysqli->connect_errno) {
die('连接失败: ' . $mysqli->connect_error);
}
// 检查当前连接字符集
$charsetInfo = $mysqli->get_charset();
echo '当前连接字符集: ' . $charsetInfo->charset . PHP_EOL;
// 如果不是 utf8mb4,则设置为 utf8mb4
if ($charsetInfo->charset !== 'utf8mb4') {
if (!$mysqli->set_charset('utf8mb4')) {
die('设置字符集失败: ' . $mysqli->error);
} else {
echo '已将连接字符集设置为 utf8mb4' . PHP_EOL;
}
}
// 示例插入含有 Emoji 的数据
$stmt = $mysqli->prepare('INSERT INTO messages (content) VALUES (?)');
$content = '测试 Emoji ?? ??';
$stmt->bind_param('s', $content);
if ($stmt->execute()) {
echo '数据插入成功!' . PHP_EOL;
} else {
echo '插入失败: ' . $stmt->error . PHP_EOL;
}
$stmt->close();
$mysqli->close();
?>
要完全支持 Emoji 和其他 4 字节字符,除了代码层面的设置,还需要:
数据库、表、字段字符集设置:
ALTER DATABASE your_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
连接参数: 确保 MySQL 配置文件 my.cnf 中 [mysqld] 部分包含:
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
使用 mysqli::get_charset 可以帮助我们在代码中动态检查连接字符集是否正确,并在必要时进行修正。结合数据库和表的正确配置,可以彻底解决 Unicode 表情符号无法存储的问题。这样,用户就可以畅快地在你的应用中使用各种 Emoji,而不必担心丢失或乱码。