插件自己建的表里,昵称带 emoji 的记录落库后显示成三个问号,导出来看原值已经没了。同一篇文章标题里的 emoji 在主表里却完好无损。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

CREATE TABLE {$wpdb->prefix}abc_log (
  id bigint unsigned NOT NULL AUTO_INCREMENT,
  note varchar(255) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE 没写字符集,表跟着库的默认值走,老库默认还是 utf8,四字节字符直接被截断。建表时不显式声明,换一台服务器结果就变。这一点先确认清楚,后面就不用反复试。

「插件建表字符集」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

具体做法是,建表语句末尾补上字符集和排序规则 两项都要写全;已经建好的表用 ALTER 改成一致 单表和整库分别确认;改完重连一次数据库 让连接字符集也跟上。

改完照着核一遍,表里重新写入带 emoji 的记录后原样显示,SHOW CREATE TABLE 里字符集是 utf8mb4。

作者 9823189