要让laravel项目真正支持emoji、生僻汉字和中文全文搜索,必须从连接层开始统一强制使用utf8mb4字符集,只改数据库或表结构而忽略pdo初始化命令,会导致插入时直接报错sqlstate[hy000]: general error: 1366 incorrect string value。

确认MySQL服务端已启用utf8mb4
打开my.cnf(Linux)或my.ini(Windows),在[mysqld]段落中添加两行:
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
重启MySQL服务后,执行mysql -u root -p -e "SHOW VARIABLES LIKE 'character_set_server';",确认输出值为utf8mb4。若仍是utf8,说明配置未生效或未重启服务。
修改Laravel数据库连接配置
编辑config/database.php,在mysql连接配置块中,必须同时设置三项:
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'options' => [【PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"】]
⚠️ 注意:DB_CHARSET=utf8mb4写在.env里完全无效——Laravel官方代码根本没读这个变量,纯属误导。
全局设置默认字符串长度
在AppServiceProvider的boot()方法中加入:
Schema::defaultStringLength(191);
这一步不可跳过。因为utf8mb4下VARCHAR(255)字段索引长度会超限(InnoDB单列索引最大767字节),不设会导致迁移失败报错“Specified key was too long”。Laravel 5.4+ 默认仍用255,必须手动覆盖。
迁移文件中显式声明表级字符集
方法一:在迁移文件末尾追加原生SQL语句
DB::statement("ALTER TABLE posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
方法二:在Schema::create()中为每张表指定引擎与字符集(更稳妥)
$table->engine = 'InnoDB';
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
⚠️ 注意:仅靠config/database.php设置无法影响php artisan migrate生成的建表SQL,Laravel 9.x之前默认仍用utf8建表。
为关键字段单独指定排序规则
第一步:检查字段是否需模糊中文检索或区分大小写
第二步:在迁移中使用collation()方法(仅string/text/tinyText等文本类型支持)
$table->string('title')->collation('utf8mb4_unicode_ci');
$table->text('content')->collation('utf8mb4_bin');
第三步:运行php artisan migrate --pretend,确认生成SQL中包含COLLATE子句。整数、布尔等非文本字段调用collation()会静默失效,无需尝试。











