sqlite_open()在PHP 7.0+中已彻底移除,调用即报Fatal error;必须启用sqlite3扩展、使用绝对路径或__DIR__拼接确保文件可写,并开启WAL模式提升并发。

sqlite_open() 在 PHP 7.0+ 中已彻底移除,调用即报 Fatal error: Call to undefined function sqlite_open() —— 别再查旧教程、别再试这个函数,它不存在。
确认 SQLite3 扩展是否真就绪
很多人写的代码没错,但连对象都 new 不出来,根源是扩展压根没加载。不是“PHP 支持 SQLite”,而是“你这台机器上的 PHP 是否启用了 sqlite3 扩展”。
- 运行
php -m | grep -i sqlite,必须看到sqlite3(pdo_sqlite可选,除非你用 PDO) - Windows 下检查
php.ini:确保extension=php_sqlite3.dll这行没被分号注释,且 DLL 文件真实存在 - 在脚本里加一句
var_dump(extension_loaded('sqlite3'));,输出bool(true)才算过关 - Alpine 容器或极简编译版 PHP 常默认不带
sqlite3,得手动apk add php82-sqlite3(版本按需替换)
用 SQLite3 类连接并自动建库,路径写错就静默失败
SQLite 数据库 = 一个文件。实例化 SQLite3 就会尝试创建该文件,但失败时不会报“找不到库”,而是抛出 unable to open database file —— 很可能是因为路径指向了不可写的目录,或父目录根本不存在。
- 绝对路径最稳:
new SQLite3('/var/www/myapp/data/app.db') - 用
__DIR__拼接更可靠:new SQLite3(__DIR__ . '/data/app.db'),避免工作目录(getcwd())变化导致文件生成到意外位置 - 确保
data/目录存在,且 Web 用户(如www-data或_www)有rwx权限:chmod 755 data/ && chown www-data:www-data data/ - 首次
exec("CREATE TABLE ...")才真正触发文件落盘;只new SQLite3(...)不执行语句,某些 PHP 版本下文件可能仍为空
插入后取自增 ID,别用 mysqli_insert_id() 那套
SQLite3 类不兼容 MySQL 风格的插入后 ID 获取方式。用错函数不仅拿不到值,还可能误导你认为插入失败。
- 正确方法是调用
$db->lastInsertRowID(),它返回上一次INSERT语句生成的主键值 - 必须在
exec()或prepare()->execute()成功后立刻调用,延迟或中间穿插其他查询会覆盖结果 - 如果表没定义
INTEGER PRIMARY KEY(或AUTOINCREMENT),lastInsertRowID()返回 0 或无效值 - 参数化插入时,
lastInsertRowID()依然有效,不需要额外处理:$stmt->execute(); $id = $db->lastInsertRowID();
并发写入卡住?PRAGMA journal_mode = WAL 是关键开关
默认回滚日志模式下,多请求同时写库极易触发 database is locked。这不是代码 bug,是 SQLite 的锁机制限制 —— WAL 模式能显著缓解,但必须手动开启且有前提。
立即学习“PHP免费学习笔记(深入)”;
- 连接后立即执行:
$db->exec("PRAGMA journal_mode = WAL");(注意:不是PRAGMA synchronous = NORMAL等其他设置) - WAL 要求文件系统支持原子性写入(绝大多数 ext4、APFS、NTFS 没问题;NFS、某些 FAT 变体不支持)
- 开启后会产生
-wal和-shm两个附加文件,不能单独删除,否则损坏数据库 - 若应用部署在容器或只读文件系统中,WAL 可能失败,此时应降级为
PRAGMA locking_mode = EXCLUSIVE并控制写入串行化



















