必须将laravel全链路统一为utf8mb4字符集,涵盖http请求、php源码(utf-8无bom)、mysql服务端(my.cnf设character-set-server=utf8mb4)、连接层(config/database.php显式配置charset/collation及pdo初始化命令)、已有库表(alter database/table convert to utf8mb4)、字段级(迁移中用->collation()或db::statement()),并修复windows下artisan终端编码(chcp 65001)。

确保Laravel全链路UTF-8编码一致性,就是让从HTTP请求、PHP源码、数据库连接、表结构、字段内容到Artisan命令行全部统一使用utf8mb4字符集,否则中文、emoji、生僻字会显示为、???或直接报SQLSTATE[HY000]错误。
PHP源码与模板文件编码设置
打开你的文本编辑器设置,将项目所有PHP文件、Blade模板、JSON配置、迁移文件、Seeder文件的默认保存编码强制设为UTF-8(无BOM)。TextMate、VS Code、PhpStorm默认即为UTF-8;若用Dreamweaver或老旧Notepad++,需手动在“编码→字符集”中选“UTF-8”,并取消勾选“BOM”。【BOM会导致Laravel路由加载失败或空白页】。检查已有文件是否含BOM:在Linux下执行file -i app/Http/Controllers/HomeController.php,返回中含charset=utf-8且无with-bom字样才安全。
数据库服务端全局配置
编辑MySQL配置文件:/etc/mysql/my.cnf(Linux)或C:\ProgramData\MySQL\MySQL Server 8.0\my.ini(Windows),在[mysqld]段末尾添加:
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
skip-character-set-client-handshake
重启MySQL服务:sudo systemctl restart mysql(Linux)或服务管理器中重启MySQL 8.0服务(Windows)。登录MySQL执行:SHOW VARIABLES LIKE 'character_set_server';,确认返回值为utf8mb4;再执行:SHOW VARIABLES LIKE 'collation_server';,确认返回值为utf8mb4_unicode_ci。
Laravel数据库连接层强制声明
在config/database.php的'mysql'配置块内,必须显式覆盖四项:
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'options' => [
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
],
【仅改.env中的DB_CHARSET无效——Laravel官方配置根本不读这个变量】。删除.env里所有以DB_CHARSET开头的行,避免误导。
已有数据库与表结构升级
第一步:登录MySQL,切换到目标库:USE your_database_name;
第二步:升级整个数据库默认字符集:ALTER DATABASE your_database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
第三步:对每张表执行转换(替换table_name):ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。这一步会重写所有字段,包括TEXT、VARCHAR、TINYTEXT等,但不会动INT、DATETIME类型。
第四步:检查关键字段是否已生效——执行:SHOW FULL COLUMNS FROM users;,观察Collation列是否全为utf8mb4_unicode_ci。若仍有utf8_general_ci,说明该字段未被CONVERT覆盖,需单独执行:ALTER TABLE users MODIFY name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
新建迁移文件中强制指定字段级字符集
方法一:在迁移文件中为字符串字段显式加->collation('utf8mb4_unicode_ci')
$table->string('title')->collation('utf8mb4_unicode_ci');
$table->text('content')->collation('utf8mb4_unicode_ci');
方法二:对整张表执行后置SQL(更稳妥,绕过Laravel Schema Builder旧版bug)
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->string('body');
$table->timestamps();
});
DB::statement("ALTER TABLE comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
注意:整数、布尔、时间类型字段不支持collation,强行调用会报错。
Artisan命令行终端编码修复(Windows专属)
打开项目根目录下的artisan文件,在#!/usr/bin/env php下方插入:
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
exec('chcp 65001 > NUL');
}
保存文件,关闭所有CMD/PowerShell窗口,重新打开终端并运行php artisan list。若命令帮助文字中中文不再显示为方块或乱码,说明生效。此操作只影响当前PHP进程启动的终端编码,不修改系统全局设置。











