必须同时配置字符集与ssl参数:dsn中声明utf8mb4,options数组注入ssl模式及证书路径,二者不可互替;需验证mysql服务端字符集和ssl均启用,并清除缓存后用db::connection()->getpdo()和select确认生效。

当Laravel应用需要同时满足数据库字符集统一(如utf8mb4)和强制SSL加密连接时,必须确保两者在PDO连接参数中不冲突、不覆盖——字符集设置在DSN中声明,SSL参数必须通过options数组注入,否则SSL会被忽略或字符集失效。
确认MySQL服务端支持utf8mb4与SSL共存
登录数据库执行:SHOW VARIABLES LIKE 'character_set%'; 和 SHOW VARIABLES LIKE 'have_ssl';。两项结果均需返回utf8mb4和YES,否则后续配置无效。
若have_ssl为DISABLED,需先在MySQL服务端启用SSL并重启mysqld;若字符集非utf8mb4,需修改my.cnf中character-set-server = utf8mb4并重启。
在.env中定义字符集与SSL模式开关
编辑.env文件,确保以下四行存在且值明确:
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
DB_SSL_MODE=required
DB_SSL_CA=/absolute/path/to/rds-combined-ca-bundle.pem
【DB_SSL_CA路径必须是绝对路径】,相对路径(如storage/ssl/ca.pem)会导致PDO静默失败,且无明确报错。
修改config/database.php注入字符集与SSL参数
找到mysql配置数组,在'charset'和'collation'字段后,添加'dsn'字段显式声明字符集:
'dsn' => env('DB_DSN', 'mysql:charset='.env('DB_CHARSET', 'utf8mb4').';collation='.env('DB_COLLATION', 'utf8mb4_unicode_ci'))
接着在mysql数组内新增'options'键,按环境变量动态注入SSL参数:
第一步:定义SSL模式映射常量
$sslMode = env('DB_SSL_MODE', 'disabled');
第二步:根据模式构造options数组
'options' => array_filter([
PDO::MYSQL_ATTR_SSL_MODE => match($sslMode) {
'required' => PDO::MYSQL_ATTR_SSL_MODE_REQUIRED,
'preferred' => PDO::MYSQL_ATTR_SSL_MODE_PREFERRED,
'disabled' => PDO::MYSQL_ATTR_SSL_MODE_DISABLED,
default => PDO::MYSQL_ATTR_SSL_MODE_DISABLED,
},
PDO::MYSQL_ATTR_SSL_CA => $sslMode !== 'disabled' ? database_path(env('DB_SSL_CA')) : null,
PDO::MYSQL_ATTR_SSL_CERT => $sslMode !== 'disabled' && env('DB_SSL_CERT') ? database_path(env('DB_SSL_CERT')) : null,
PDO::MYSQL_ATTR_SSL_KEY => $sslMode !== 'disabled' && env('DB_SSL_KEY') ? database_path(env('DB_SSL_KEY')) : null,
], fn($v) => $v !== null)
注意:PDO::MYSQL_ATTR_SSL_MODE_REQUIRED是整型2,不是字符串"required";写成字符串会导致连接降级为明文且无报错。
清除配置缓存并验证连接
运行php artisan config:clear,否则旧配置仍被读取,SSL和字符集设置全部失效。
执行php artisan tinker → 输入DB::connection()->getPdo()->getAttribute(PDO::ATTR_CONNECTION_STATUS),返回结果应含SSL字样;再执行DB::select('SELECT @@character_set_database, @@collation_database'),确认两列均为utf8mb4和utf8mb4_unicode_ci。











