thinkphp 5 连接 sqlite 必须同时满足四个硬性条件:安装 think-sqlite 扩展、dsn 格式为 sqlite:/绝对路径/db.db、路径全英文无空格、删除 hostname/database 等冗余字段,缺一即报 unable to open database file。

ThinkPHP 5 连接 SQLite 不是“配对 type 就行”,而是必须满足四个硬性条件:装对扩展、写对 DSN、用绝对路径、删干净冗余字段。少一个,SQLSTATE[HY000] Unable to open database file 就会反复出现。
think-sqlite 扩展必须手动装,pdo_sqlite 不够用
PHP 系统级启用了 pdo_sqlite(php -m | grep sqlite 能看到),不代表 ThinkPHP 就能用 SQLite。TP5 默认不带 SQLite 适配器,缺的是 topthink/think-sqlite 这个 Composer 包。
- 运行
composer require topthink/think-sqlite,不是think-orm或其他变体 - 确认
config/database.php中'type' => 'sqlite',且该配置被实际加载(可加var_dump(config('database'));验证) - Windows 下别信“已安装扩展”——CLI 和 Web SAPI(如 php-fpm)可能用不同 php.ini,各自都要检查
extension=php_pdo_sqlite.dll(Windows)或extension=pdo_sqlite.so(Linux/macOS)是否启用
DSN 必须是 sqlite:/absolute/path/to/db.db,不能省略前缀也不能用相对路径
TP5 的 SQLite 驱动靠 DSN 协议头识别类型,'dsn' => '/runtime/app.db' 或 'dsn' => 'D:\app.db' 都会被当成 MySQL 处理,最终连错驱动或报错 unable to open database file。
- 正确格式只有一种:
'dsn' => 'sqlite:' . __DIR__ . '/../runtime/db/app.db' - 路径必须绝对,
./data/app.db或../runtime/app.db在 CLI 下可能指向 public/ 目录,Web 下又指向入口目录,行为不一致 - Windows 也强制用正斜杠:
sqlite:C:/project/runtime/app.db,反斜杠C:\project\...会被 SQLite 解析失败 - 路径中不能含空格或中文;文件名建议全英文+下划线,如
app_data.db
database.php 里 hostname/database/username 等字段必须留空或删除
SQLite 是文件型数据库,不走网络协议,也不需要用户名密码。但 TP5 的连接器若看到这些字段非空,可能尝试绑定无效参数,导致初始化失败或静默降级。
- 只保留必要字段:
'type'、'dsn'、'charset'(可选)、'params'(如需超时控制) -
'hostname'、'database'、'username'、'password'、'hostport'全部设为空字符串或直接删掉 - 如果用了多环境配置(如
database_dev.php),确保APP_ENV=dev且该文件被正确加载——TP5 不自动合并配置,改了 .env 不等于改了配置文件
迁移命令和业务代码必须共用同一份 DSN 路径
php think migrate:run 成功建表,但控制器里查 user 表却报 no such table,90% 是因为 CLI 和 Web 请求读到了不同 DSN —— 常见于相对路径、环境变量未生效、或 runtime 目录权限不对。
- 执行迁移前,先在命令行跑一句:
php -r "var_dump(config('database.default.dsn'));",确认输出的是你预期的绝对路径 - 检查
runtime/db/目录是否存在且 PHP 进程可写(CLI 下用php -r "var_dump(is_writable('runtime/db'));",Web 下看日志或临时加一行file_put_contents('runtime/db/test', 'ok');) - 别用
:memory:做开发配置——它每次请求新建库,迁移建的表根本不会持久,调试可以,但容易误判连接是否成功 - 并发写入频繁时加
'params' => [PDO::ATTR_TIMEOUT => 5],否则database is locked错误会高频出现
最易忽略的一点:TP5 的 SQLite 连接完全不依赖 .env 文件里的 DB_TYPE 或 DB_DATABASE,所有关键信息必须落在 config/database.php 的 dsn 字段里,且路径拼接必须用 __DIR__ 或 App::getRuntimePath() 这类运行时解析方式,硬编码路径迟早出问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











