必须统一mysql连接层、服务端、数据库/表/列三级utf8mb4配置:在config/database.php设charset/collation/options三项,my.cnf配character-set-server,手动alter database/table升级,迁移中用collation()或convert to,并设defaultstringlength(191)防索引超限。

要让Laravel应用正确存储emoji、生僻汉字和中文模糊搜索结果,必须穿透连接层、表层、列级三层字符集配置,光改其中一层会导致存入乱码或SQL报错。
统一MySQL连接层字符集
在config/database.php的mysql连接配置块中,添加三项关键设置:
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'options' => [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"]
缺一不可——【不加PDO初始化命令,Laravel 8+在某些PDO版本下仍会走默认utf8连接】。.env里设DB_CHARSET=utf8mb4完全无效,Laravel官方配置根本没读这个变量。
确保MySQL服务端支持utf8mb4
编辑my.cnf(Linux)或my.ini(Windows),在[mysqld]段落下确认存在:
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
重启MySQL服务后,执行SHOW VARIABLES LIKE 'character_set%';,检查character_set_server和character_set_database是否均为utf8mb4。若不是,配置未生效。
已有数据库和表不会自动升级,需手动执行:ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; 和 ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。
迁移文件中为字段显式指定排序规则
方法一:使用collation()链式调用(仅适用于string()、text()等支持类型)
$table->string('title')->collation('utf8mb4_bin');
方法二:对整张表强制转换(适用于已建表或大字段)
在Schema::create()之后追加:DB::statement("ALTER TABLE posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
方法三:避免索引长度超限(Laravel 9.x前默认建表仍用utf8)
在AppServiceProvider::boot()中加入:Schema::defaultStringLength(191);,并配合所有迁移中显式声明:$table->string('slug')->charset('utf8mb4');
【整数类型如integer()不支持collation(),调用会静默失败】
验证迁移生成的SQL是否带COLLATE
第一步:运行php artisan migrate --pretend
第二步:检查输出SQL中是否含COLLATE utf8mb4_unicode_ci字样
第三步:若无,则说明迁移未穿透到列级——可能因字段类型不支持collation,或Laravel版本低于5.8,或PDO驱动不识别该参数
第四步:直接用DB::statement()执行带MODIFY COLUMN ... CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci的手动语句,但必须自行包裹事务与回滚逻辑











