PHP 8.2 默认内置 sqlite3 和 pdo_sqlite 扩展,开箱即用;需通过 php -m 验证两者均加载,用绝对路径和正确权限初始化连接,并启用 WAL 模式防锁表。

PHP 8.2 默认已内置 sqlite3 和 pdo_sqlite 扩展,只要没被手动禁用,开箱即用——不需要额外安装驱动、不用编译、也不依赖外部服务。
确认扩展是否真在运行
很多人以为“PHP 8.2 就自带 SQLite”,结果 new SQLite3('db.db') 报错 Class not found,其实是扩展被注释或没加载成功。
- 运行
php -m | grep -i sqlite,必须同时看到sqlite3和pdo_sqlite两行;只有一行,PDO 连接会报could not find driver,SQLite3 类可能直接不可用 - Windows 用户检查
php.ini中是否有extension=php_sqlite3.dll和extension=php_pdo_sqlite.dll,且前面没分号 - Linux/macOS 检查
extension=sqlite3.so和extension=pdo_sqlite.so是否启用;某些 phpEnv 或自编译版本默认不带 SQLite,得重装并加--with-sqlite3 --with-pdo-sqlite - 脚本内验证:
var_dump(extension_loaded('sqlite3') && extension_loaded('pdo_sqlite'));返回true才算到位
用 SQLite3 类连接:路径和权限最容易翻车
SQLite3 是 PHP 8.2 最轻量、最直接的接入方式,但它对路径和文件系统权限极其敏感——写错一个字符,就静默创建空库;权限不对,直接报 unable to open database file。
- 永远用绝对路径:
new SQLite3(__DIR__ . '/data/app.db'),别用'app.db'这种相对路径,当前工作目录(getcwd())受 CLI / Web Server 启动方式影响极大 - 父目录必须存在且可写:比如
__DIR__ . '/data/'目录要提前mkdir -p data && chmod 755 data,Web 用户(如www-data或_www)必须有写权限 - 首次
new SQLite3(...)会自动建库文件,但不会建目录;如果目录不存在或不可写,就失败,不是报错而是返回false,且不抛异常 - 建表时记得定义主键:
id INTEGER PRIMARY KEY,否则$db->lastInsertRowID()可能返回 0 或无效值
PDO 连接 SQLite:DSN 写法和错误模式是关键
PDO 更适合需要事务、预处理或未来可能换数据库的项目,但它的默认行为容易掩盖真实问题——比如 SQL 语法错只报 SQLSTATE[HY000],看不出到底是表不存在还是字段名拼错了。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- DSN 必须写成
sqlite:/abs/path/to/db.sqlite(Linux/macOS)或sqlite:C:\path\to\db.sqlite(Windows),开头的sqlite:不能漏,路径不能是相对的 - 必须设错误模式:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION),否则exec()失败只返回false,不抛异常,很难调试 - 避免模拟预处理:
setAttribute(PDO::ATTR_EMULATE_PREPARES, false),否则绑定参数个数不匹配时不会报错,而是静默失败 - 查错时用
$pdo->errorCode()和$pdo->errorInfo(),比$e->getMessage()更准;例如字段名含短横线(user-id)却没加反引号,就会在这里暴露
WAL 模式不是可选项,是并发写入的刚需
默认的 rollback journal 模式在多请求同时写入时极易触发 database is locked。PHP 8.2 + SQLite 3.26+ 环境下,WAL 是必须打开的配置,否则小流量应用都可能卡住。
- 连接后立即执行:
$pdo->exec("PRAGMA journal_mode = WAL")或$db->exec("PRAGMA journal_mode = WAL") - 验证是否生效:
$db->query("PRAGMA journal_mode")->fetchArray()[0]应返回wal - 注意:
-wal和-shm文件必须和主库文件在**同一文件系统**(不能跨挂载点),否则 WAL 自动退化回 DELETE 模式,你根本察觉不到 - WAL 不持久化,每次连接都要重设;不要指望只初始化一次就一劳永逸
真正麻烦的从来不是“怎么连”,而是“为什么连上了却读不到数据”或者“为什么一并发就锁死”——路径错、权限错、WAL 跨文件系统、错误模式没开,这四点覆盖了 90% 的线上 SQLite 故障。动手前先跑通 php -m | grep sqlite 和 ls -l data/,比反复改代码快得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










