数据库配置最终生效于main-local.php文件,该文件被main.php引入且通常被.gitignore排除;需确保其存在、包含完整db组件配置并以return $config;结尾。

数据库配置写在哪儿:main-local.php 是最终生效位置
Yii 2.0.49 的数据库配置不直接写在 main.php,而是在环境隔离机制下落到 main-local.php(或 db-local.php,取决于项目结构)。这个文件默认被 main.php 通过 require_once 引入,且通常被 .gitignore 排除——这是故意的,避免密钥泄露。
常见错误现象:CDbConnection failed to open the DB connection,往往是因为改了 main.php 却没动 main-local.php,或者文件根本不存在。
- 检查
protected/config/(传统结构)或config/(高级模板)下是否存在main-local.php - 若不存在,手动创建,内容必须包含完整的
'components' => ['db' => [...]]配置段 - 确保该文件末尾有
return $config;,否则 Yii 加载会失败并报错Invalid Configuration
Db 组件关键参数:host、dbname、username、password 缺一不可
MySQL 连接失败八成卡在这四个字段。Yii 2.0.49 使用的是 PDO 封装,所以 dsn 字段虽然可写,但更推荐拆解为独立键值——清晰、易调试、兼容旧版迁移逻辑。
使用场景:本地开发用 localhost,Docker 环境必须用容器名(如 mysql),不能写 127.0.0.1(会绕过 Unix socket,且可能触发 host 检查失败)。
-
'dsn' => 'mysql:host=localhost;dbname=myapp'可以省略,Yii 会自动拼接 -
'username'和'password'不能为空字符串,设为空会导致认证失败,报错Access denied for user ''@'localhost' - 如果 MySQL 启用了
sql_mode=STRICT_TRANS_TABLES(新版默认),建议加'initSQLs' => ["SET NAMES utf8mb4"],否则中文插入可能截断
连接失败时优先查 PDO::ATTR_ERRMODE 和 charset
默认情况下 Yii 不暴露底层 PDO 错误详情,只抛出笼统的 CDbException。想看到真实报错(比如 “Unknown database” 或 “Plugin ‘caching_sha2_password’ is not loaded”),得主动开启异常模式。
性能影响:开启 PDO::ERRMODE_EXCEPTION 仅影响错误路径,不影响正常查询速度;但 charset 设置错误会导致每次查询前多一次 SET NAMES,轻微开销。
- 在
db配置里加'attributes' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] -
'charset'必须与 MySQL 实际库表编码一致,utf8mb4是安全选择,utf8在 Yii 2.0.49 中实际映射为utf8mb3,存 emoji 会失败 - 若用阿里云 RDS 或腾讯云 CDB,注意它们默认关闭
local_infile,如果代码里调用了LOAD DATA INFILE,需额外加'emulatePrepare' => true
测试连通性别只靠 Yii::app()->db->active
Yii::app()->db->active 只检查连接对象是否已初始化,并不真正发包探活。很多开发者以为返回 true 就代表能用,结果第一次 createCommand() 时才崩。
正确做法是执行一条轻量 SQL,比如 SELECT 1,并捕获异常。这也是 Yii 自带命令行工具 yiic shell 测试 db 的原理。
- 临时测试可在入口脚本末尾加:
try { Yii::app()->db->createCommand('SELECT 1')->queryScalar(); echo "OK\n"; } catch (Exception $e) { echo "FAIL: " . $e->getMessage() . "\n"; } - 生产环境禁止用这种方式做健康检查接口,应改用 TCP 连接探测(如
fsockopen($host, $port)),避免数据库压力 - 如果用的是长连接(
'persistent' => true),要注意 MySQL 的wait_timeout,超时后首次查询会报MySQL server has gone away,需配合重连逻辑











