PHP 8.4 默认内置 pdo_sqlite 扩展,无需额外安装;需用 php -m 验证启用状态,DSN 必须用绝对路径,连接后应设置 ERRMODE 和 FETCH_MODE,并建议执行 PRAGMA journal_mode = WAL 提升并发性能。

PHP 8.4 默认已内置 pdo_sqlite 扩展,只要没手动禁用,直接 new PDO 就能连 SQLite3 —— 不需要额外安装扩展,也不用担心版本兼容问题。
确认 pdo_sqlite 是否启用
PHP 8.4 编译时默认启用 pdo_sqlite,但某些定制环境(如 Alpine 容器、精简版 PHP 包)可能剔除了它。运行以下命令验证:
php -m | grep pdo_sqlite
如果无输出,说明未启用。此时需检查:
-
php.ini中是否存在extension=pdo_sqlite(Linux/macOS)或extension=php_pdo_sqlite.dll(Windows),且未被注释 - 若使用 Docker,Alpine 镜像需额外安装:
apk add php84-sqlite3(注意包名含84) - CLI 和 Web SAPI(如 Apache/FPM)的
php.ini可能不同,用phpinfo()确认 Web 环境实际加载的配置
DSN 写法与路径陷阱
SQLite 的 DSN 格式是 sqlite:/绝对路径/xxx.db 或 sqlite:相对路径/xxx.db,但相对路径容易出错:
立即学习“PHP免费学习笔记(深入)”;
- “相对”是相对于 脚本当前工作目录(
getcwd()),不是文件所在目录;Web 请求下常为 Web 根目录,CLI 下则是执行命令的目录 - 推荐一律用绝对路径:例如
sqlite:/var/www/db/app.db(Linux)或sqlite:C:\inetpub\wwwroot\db\app.db(Windows) - 路径中含空格或中文?必须 URL 编码(如
sqlite:%2Fhome%2Fuser%2Fmy%20db.db),但更稳妥的做法是避免这类字符 - PHP 进程必须对数据库文件及其父目录有
read+write权限(Linux/macOS 下常见错误:SQLSTATE[HY000]: General error: 14 unable to open database file)
连接后必须设置的两个属性
刚 new PDO 后不设属性,会踩两个坑:错误静默失败、查询结果格式难用。
-
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION):否则 SQL 错误只返回false,很难定位问题 -
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC):否则fetch()默认返回数字索引数组,字段名丢失 - 可选但强烈建议:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false),禁用模拟预处理,让 SQLite 原生处理参数绑定(PHP 8.4 下此为默认值,但显式声明更清晰)
事务与 WAL 模式提升并发写入
SQLite 默认是回滚日志(Rollback Journal)模式,高并发写入时易触发 database is locked 错误。PHP 8.4 中可通过 PRAGMA 开启 WAL:
- 连接后立即执行:
$pdo->exec("PRAGMA journal_mode = WAL"),返回"wal"表示成功 - WAL 模式下读写可并行,但需确保数据库文件所在文件系统支持原子性(绝大多数现代文件系统都支持)
- 事务必须显式控制:
$pdo->beginTransaction()→$pdo->commit()或$pdo->rollback();自动提交(autocommit)开启时,每条语句都是独立事务,无法保证多语句原子性 - 注意:WAL 文件(
xxx.db-wal和xxx.db-shm)需与主库文件同目录且有写权限,否则 WAL 会退化为普通日志
真正容易被忽略的是:WAL 模式开启后,数据库文件锁机制变了,多个进程/线程同时读写时行为和传统模式不同;如果应用混合了 CLI 脚本和 Web 请求访问同一 DB,务必测试 WAL 下的锁表现,别只在单线程下验证。



















