mysql ThinkPHP连接mysql配置_mysql框架类库说明

来源:这里教程网 时间:2026-02-28 20:41:02 作者:

ThinkPHP 连接 MySQL 的配置文件在哪

ThinkPHP 6 默认的数据库配置在

config/database.php
文件中,不是
.env
就是它——取决于你是否启用了环境配置。若项目启用
.env
,则优先读取其中的
DB_TYPE
DB_HOST
等字段,
config/database.php
里对应值会被覆盖。

常见误操作:改了

config/database.php
却没生效,大概率是因为
.env
存在且已定义同名键,此时必须改
.env

.env
中写法示例:
DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=thinkphp
DB_USER=root
DB_PWD=123456
DB_PREFIX=tp_
注意
DB_PWD
不能含特殊字符(如
@
/
:
),否则 URL 解析会失败;需用 URL 编码,例如密码
pa@ss/word
要写成
pa%40ss%2Fword
连接超时、报
SQLSTATE[HY000] [2002] Connection refused
,先确认
DB_HOST
是容器名(Docker)还是
127.0.0.1
(宿主机)——本地开发用
127.0.0.1
,别写
localhost
(MySQL 会走 socket)

ThinkPHP 6 的 Db 类和 Query 类区别

ThinkPHP 6 把数据库操作拆成了两层:

Db
是门面类(Facade),提供静态调用入口;
Query
是实际执行查询的类,由容器自动实例化并注入连接。

你写的

Db::table('user')->where('id', 1)->find()
,背后是
Db
从容器取一个
Query
实例,再链式调用其方法。不建议手动 new
Query
,除非你要切换连接或自定义查询器。

立即学习“PHP免费学习笔记(深入)”;

多库场景下,用
Db::connect('mysql2')
获取指定连接配置的
Query
实例,而不是
new Query(['connection' => 'mysql2'])
(后者绕过容器,事务、事件监听可能失效)
Db::raw()
返回的是
Raw
对象,不是字符串,不能直接拼进 SQL 字符串里;要用于
where
field
才安全
执行原生 SQL 用
Db::execute()
(INSERT/UPDATE/DELETE)或
Db::query()
(SELECT),别混用;前者返回影响行数,后者返回二维数组

MySQL 连接参数对 ThinkPHP 的实际影响

ThinkPHP 底层用 PDO 连接 MySQL,

config/database.php
中的
params
数组会透传给
PDO::__construct()
。几个关键参数直接影响行为:

PDO::ATTR_EMULATE_PREPARES => false
:必须设为
false
,否则 LIKE 查询带
%
时可能被错误转义;ThinkPHP 默认已设,但自定义
params
时容易覆盖掉
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
:推荐显式设置,避免连上后执行
SET NAMES
多一次 round-trip;注意是
utf8mb4
,不是
utf8
(后者不支持 emoji)
PDO::ATTR_TIMEOUT => 3
:连接超时秒数,单位是秒;值太小会导致高并发下频繁报
SQLSTATE[HY000] [2002] Connection timed out
若开启
deploy => 1
(读写分离),
params
只作用于主库;从库需单独配
slave_params

常见报错与定位方法

遇到数据库报错,别急着搜错误全文。ThinkPHP 的 PDO 异常默认只显示 SQLSTATE 和驱动错误号,真正有用的线索藏在异常对象的

getPrevious()
或日志里。

SQLSTATE[42000]: Syntax error or access violation
:通常是字段不存在、关键字冲突(如用
order
当字段名没加反引号)、或 MySQL 版本不兼容(如 8.0+ 的窗口函数在 5.7 下运行)
查不到数据但 SQL 拷到 Navicat 能查到:检查
DB_PREFIX
是否配置正确,以及
table()
方法是否漏写了前缀(
Db::table('user')
实际查的是
tp_user
事务不生效:确认用的是
Db::transaction()
包裹,且所有操作都基于同一个
Db
实例(不要在事务块里混用
new Model()
,Model 默认用独立连接)
日志里出现
[ SQL ] INSERT INTO `tp_user` ...
但表没数据:可能是自动提交被关了,检查
params
是否误设了
PDO::ATTR_AUTOCOMMIT => 0
实际项目里,最常被忽略的是
.env
config/database.php
的优先级关系,以及
PDO::ATTR_EMULATE_PREPARES
被覆盖导致的模糊查询失效——这两处出问题,现象都像“SQL 没报错但结果不对”。

相关推荐