请注意,MySQL 的 utf8 编码最多为 3 个字节,无法编码 *所有* Unicode 字符。
如果您需要编码超出 BMP(基本多语言平面)的字符,例如表情符号或其他特殊字符,您将需要使用其他编码,例如 utf8mb4 或任何其他支持更高平面的编码。Mysql 将丢弃以 4 个字节(或更多)编码的任何字符。
有关此问题的更多信息,请参阅 https://dev.mysqlserver.cn/doc/refman/5.7/en/charset-unicode-utf8mb4.html
理想情况下,应在服务器级别设置适当的字符集,并在 MySQL 服务器手册的 » 字符集配置 部分中描述了如何执行此操作。或者,每个 MySQL API 都提供了一种方法,可以在运行时设置字符集。
应理解和定义字符集,因为它会影响每个操作,并包括安全隐患。例如,转义机制(例如,mysqli_real_escape_string() 用于 mysqli 和 PDO::quote() 用于 PDO_MySQL)将遵守此设置。重要的是要意识到,这些函数不会使用在查询中定义的字符集,因此例如以下操作不会影响它们
示例 #1 使用 SQL 设置字符集的问题
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
// 不会影响 $mysqli->real_escape_string();
$mysqli->query("SET NAMES utf8mb4");
// 不会影响 $mysqli->real_escape_string();
$mysqli->query("SET CHARACTER SET utf8mb4");
// 但是,这会影响 $mysqli->real_escape_string();
$mysqli->set_charset('utf8mb4');
// 但是,这不会影响它 (UTF-8 与 utf8mb4) -- 不要在这里使用破折号
$mysqli->set_charset('UTF-8');
?>
以下是演示如何在运行时使用每个 API 正确更改字符集的示例。
注意: 可能的 UTF-8 混淆
由于 MySQL 中的字符集名称不包含破折号,因此字符串“utf8”在 MySQL 中是有效的,用于将字符集设置为 UTF-8(最多 3 字节 UTF-8 Unicode 编码)。字符串“UTF-8”无效,因为使用“UTF-8”将无法更改字符集,并会引发错误。
示例 #2 设置字符集示例:mysqli
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
echo '初始字符集: ' . $mysqli->character_set_name() . "\n";
if (!$mysqli->set_charset('utf8mb4')) {
printf("加载字符集 utf8mb4 发生错误: %s\n", $mysqli->error);
exit;
}
echo '当前字符集为: ' . $mysqli->character_set_name() . "\n";
?>
示例 #3 设置字符集示例:pdo_mysql
<?php
$pdo = new PDO("mysql:host=localhost;dbname=world;charset=utf8mb4", 'my_user', 'my_pass');
?>
请注意,MySQL 的 utf8 编码最多为 3 个字节,无法编码 *所有* Unicode 字符。
如果您需要编码超出 BMP(基本多语言平面)的字符,例如表情符号或其他特殊字符,您将需要使用其他编码,例如 utf8mb4 或任何其他支持更高平面的编码。Mysql 将丢弃以 4 个字节(或更多)编码的任何字符。
有关此问题的更多信息,请参阅 https://dev.mysqlserver.cn/doc/refman/5.7/en/charset-unicode-utf8mb4.html
设置字符集后,您还应该定义“排序规则”,以提供有关如何对请求结果进行排序的信息。默认情况下,它是“utf8mb4_general_ci”,这是一个简化的排序规则集。对于 Unicode 制定的官方规则,它应该是“utf8mb4_unicode_ci”。
例如
\mysqli_set_charset($hdl, 'utf8mb4');
\mysqli_query($hdl, 'SET collation_connection = utf8mb4_unicode_520_ci');
如果没有任何字符集更改有效,并且数据是有效的 UTF8,并且在保存到 mysql 中时变得乱码。那么您的表不支持 UTF8,很可能是 Latin1 或其他东西。因此,您需要更新您的表,在 MySQL 的情况下,执行以下操作
ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8;