打开application/database.php,配置你会看到一个返回数组的数据文件。ThinkPHP 5 的配置数据库配置全在这里,没有藏在别的数据地方。默认情况下,配置TP5 已经给了一套本地开发的数据参数,但直接用大概率连不上——密码是配置空的,数据库名是数据 thinkphp,而你的配置机器上未必有这个库。
先看几个必须改的数据键:type 通常是 mysql,hostname 写 127.0.0.1 比写 localhost 稳,配置因为后者在某些 PHP 版本下会走 socket 连接,数据报错信息反而不直观。配置database 填你实际建好的数据库名,username 和 password 按本地 MySQL 的配置账号来。hostport 默认 3306,没改过就不用动。
有个细节容易被忽略:prefix 表前缀。如果你在 database 里设了 'prefix' => 'tp_',那写模型查 tp_user 表时,模型名用 User 就行,TP5 会自动拼上前缀。但用原生查询 Db::query('select * from user') 时,前缀不会自动加,得自己写全 tp_user。两种写法混着用,很容易出现“表不存在”的报错,查半天发现是前缀问题。
调试模式下的配置可以更“松”一点。'debug' => true 时,数据库报错会直接抛出 SQL 语句和错误位置。生产环境记得关掉,改成 false,否则敏感信息全暴露在页面上。另外 'deploy' => 0 表示单机部署,如果用了读写分离或者主从,这个值要改成 1,同时配置 rw_separate 和 master_num 这些参数。
字符集别漏了。'charset' => 'utf8mb4' 比 utf8 更值得用,尤其是存 emoji 或者生僻字的时候。我见过有人存微信昵称带个表情符号,数据库直接报 Incorrect string value,回头改 charset 还得重建表,麻烦。建库时就指定 utf8mb4,配置里也保持一致,省事。
连接参数里有个 params 数组,可以塞 PDO 的额外选项。比如 PDO::ATTR_EMULATE_PREPARES => false,关掉模拟预处理,让 MySQL 真正做预处理,对注入防护更实在。默认 TP5 没开这个,但加上没坏处。还有 PDO::ATTR_STRINGIFY_FETCHES => false,取出来的整型就是整型,不会变成字符串,省得在 PHP 里再转一次。
如果项目要连多个数据库,不用改 database.php 里的默认配置。在 config.php 里加 'database2' => [...],然后 Db::connect('database2') 就能切过去。这招在对接老系统或者分库时挺管用,比动态改配置干净。
最后说个实际踩过的坑:hostname 用 127.0.0.1 时,如果 MySQL 只监听了 localhost 的 socket,TCP 连接会被拒。反过来,如果 MySQL 只绑了 127.0.0.1 而配置写 localhost,也可能连不上。最稳的办法是 mysql -h 127.0.0.1 -u root -p 在命令行试一下,能通再写进配置。别光看 phpMyAdmin 能打开就以为没问题,那玩意儿走的协议可能不一样。
改完配置,写个 Db::query('select 1') 跑一下,返回 [['1' => 1]] 就说明通了。不通的话,TP5 的异常页面会告诉你具体是 access denied 还是 unknown database,照着改就行。别一上来就怀疑框架,九成问题出在账号密码或者库名拼写上。