Laravel应用需确认MySQL连接、表及字段字符集均为utf8mb4:通过tinker检查PDO连接状态含charset=utf8mb4;用SHOW CREATE TABLE或information_schema验证表和字段字符集;确保database.php配置charset与collation,并在迁移文件中显式设置engine和charset;最后插入含emoji数据验证全程生效。

确认Laravel应用连接的MySQL数据库表和字段实际使用的字符集是否为utf8mb4,避免emoji存入失败、中文乱码或迁移后字符集回退。
查清当前数据库连接实际生效的字符集
打开终端,进入项目根目录,运行命令进入Tinker交互环境:php artisan tinker。
执行以下代码获取当前数据库连接的字符集配置:DB::connection()->getPdo()->getAttribute(PDO::ATTR_CONNECTION_STATUS) → 观察返回结果中是否含 【charset=utf8mb4】 字样;若显示 charset=utf8 或未出现该字段,说明连接层未生效。
这一步不能只看.env里的DB_CHARSET=utf8mb4,因为PDO连接时未显式指定charset,MySQL服务端默认值会覆盖它。
检查数据表与字段的真实字符集
方法一:用SQL直接查表结构
在MySQL客户端中执行:SHOW CREATE TABLE users;(将users换成你要验证的实际表名)→ 查看CREATE TABLE语句末尾是否包含 【ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci】。
方法二:查information_schema元数据
运行:SELECT table_name, table_collation FROM information_schema.tables WHERE table_schema = 'your_database_name' AND table_name = 'users'; → 若table_collation是utf8mb4_unicode_ci或utf8mb4_general_ci,表级字符集正确。
方法三:查具体字段
执行:SELECT column_name, character_set_name, collation_name FROM information_schema.columns WHERE table_schema = 'your_database_name' AND table_name = 'users' AND data_type IN ('varchar', 'text', 'tinytext', 'mediumtext', 'longtext'); → 每个文本类字段的character_set_name必须是utf8mb4,否则即使表级正确,字段仍可能是utf8。
验证迁移文件是否真正应用了utf8mb4
第一步:确认config/database.php中MySQL连接配置已启用charset和collation:
找到'mysql' => [...]数组,检查是否存在这两行:'charset' => 'utf8mb4', 和 'collation' => 'utf8mb4_unicode_ci',;若缺失或被注释,后续迁移不会自动设字符集。
第二步:检查最近一次迁移文件里是否显式声明了引擎和字符集:
打开database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php,在Schema::create(...)闭包内,是否有$table->engine = 'InnoDB';和$table->charset = 'utf8mb4';;Laravel 9+默认不写这两行,表会继承MySQL服务器默认值,而旧版MySQL默认是utf8。
第三步:强制重跑迁移并观察SQL输出:
执行:php artisan migrate:fresh --seed --pretend → 查看打印出的CREATE语句是否含DEFAULT CHARSET=utf8mb4;若没有,说明迁移构建器未按配置生成对应SQL,需手动补全或升级laravel/framework至v9.28+
插入测试数据并肉眼验证存储效果
在Tinker中执行:App\Models\User::create(['name' => '张三??', 'email' => 'test@example.com']);。
然后用MySQL客户端查这条记录:SELECT name FROM users ORDER BY id DESC LIMIT 1; → 如果看到完整显示“张三??”且无乱码或截断(如变成“张三??”或报错),说明utf8mb4从连接、表、字段到实际写入全程生效。
注意:如果之前已有数据,该测试仅验证新插入行为;旧数据若原用utf8存入,可能仍残留乱码,需单独转换。


















