评论摘要用 LEFT(content,20) 截断,带表情的那几条在列表页末尾显示成 ?。原文按 CHAR_LENGTH 数只有 18,看着并没有超限。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

SHOW VARIABLES LIKE 'character_set_client';
SELECT id, HEX(LEFT(content,20)), CHAR_LENGTH(content) FROM comments WHERE id=1024;

四字节字符经过非 utf8mb4 的连接传输时会被拆成两个三字节符号,截断点正好落在这中间。剩下的半个码位无法单独成字,落库就变成替换字符,页面上显示为问号。这一点先确认清楚,后面就不用反复试。

「emoji 截断」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。

改完隔一天再看一次,当场正常不代表能稳住。

具体做法是,确认连接串里的 characterEncoding 写的是 utf8mb4;表默认字符集和字段一起改 只改字段不够;截断改到应用层按码位做 不在 SQL 里截;已经写坏的摘要按 id 捞出来 用原文重新生成。

改完照着核一遍,带表情的摘要末尾是完整表情 不再出现问号 页面显示字数与 CHAR_LENGTH 一致。

作者 9823189