必须确保MySQL服务端启用utf8mb4支持,否则Laravel存取emoji和生僻汉字会报错或显示问号;需确认MySQL版本≥5.5.3,修改my.cnf/my.ini三段配置并重启服务,建库时显式指定字符集,旧库旧表须手动转换且注意索引长度限制。

要让Laravel应用正确存取emoji和生僻汉字,必须先确保MySQL服务端已启用utf8mb4支持——只改Laravel配置而忽略服务端,插入时会直接报错Incorrect string value或显示问号。
确认MySQL版本是否支持utf8mb4
执行SELECT VERSION();,结果必须是5.5.3及以上;若低于此版本,升级MySQL是唯一可行路径。
MySQL 8.0默认字符集已是utf8mb4,但旧版(如5.6、5.7)仍需手动配置,且不配就无法支撑Laravel的完整Unicode需求。
修改my.cnf或my.ini配置文件
找到真实生效的配置文件路径:运行mysqld --verbose --help | grep "Default options",输出的第一行即为实际加载路径。
在该文件中,严格按以下三段写入,缺一不可:
方法一:[client]段添加默认连接字符集default-character-set = utf8mb4
方法二:[mysql]段专用于命令行客户端自身default-character-set = utf8mb4
方法三:[mysqld]段设服务端核心参数character-set-server = utf8mb4collation-server = utf8mb4_unicode_ciinit_connect = 'SET NAMES utf8mb4'
【skip-character-set-client-handshake = FALSE】(必须显式设为FALSE,否则客户端声明的charset会被忽略)
注意:Windows下找my.ini,Linux/macOS下优先检查/etc/my.cnf或/etc/mysql/my.cnf;若用Docker,挂载的配置文件权限必须是644,否则mysqld静默跳过。
重启MySQL服务并验证
第一步:执行sudo systemctl restart mysqld(Linux)或net stop mysql && net start mysql(Windows);【仅SET GLOBAL无效,必须重启】。
第二步:登录MySQL,运行SHOW VARIABLES LIKE 'character_set%';;确认character_set_server、character_set_database、character_set_client三项均为utf8mb4。
第三步:再执行STATUS;,看“Current client”是否显示via TCP/IP;若显示via socket,说明[client]段可能未生效,此时用mysql -h 127.0.0.1 -u root -p强制走TCP连接重测。
创建新数据库时显式指定utf8mb4
即使服务端已配好,仍建议建库时明确声明,避免依赖默认值出偏差:CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
这条语句比单纯靠character-set-server更可靠——它绕过了init_connect对SUPER用户的失效问题,也规避了某些MySQL发行版对默认值的覆盖行为。
已有数据库必须手动转换
第一步:执行ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
第二步:逐个转换表,例如:ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
第三步:对含TEXT/BLOB字段的表,先收缩索引长度(如VARCHAR(255) → VARCHAR(191)),否则可能因max key length is 767 bytes报错。
这一步不可跳过。character-set-server只影响新库新表,老库老表的字符集完全不变,哪怕SHOW CREATE TABLE看着像utf8mb4,字段内部实际编码仍是旧的。


















