绝大多数问题出在路径、权限或错误处理没开对:需确认pdo_sqlite扩展真正启用,DSN用绝对路径或__DIR__拼接,连接后立即设置PDO::ERRMODE_EXCEPTION和WAL模式,并用prepare/bindValue防注入。

能连上,但数据查不到、表建不成功、报错信息像天书——绝大多数问题出在路径、权限或错误处理没开对,而不是驱动本身。
确认 pdo_sqlite 扩展已真正启用
光在 php.ini 里取消注释 extension=pdo_sqlite 不够,还得验证它确实加载了。Windows 下是 php_pdo_sqlite.dll,Linux/macOS 通常是内置的,但某些精简版 PHP 可能没编译进去。
- 命令行执行
php -m | grep sqlite,必须同时看到pdo_sqlite和sqlite3(后者非必需但建议有) - 如果只看到
sqlite3没有pdo_sqlite,new PDO('sqlite:db.db')会直接抛出PDOException: could not find driver - Web 环境下用
phpinfo()查看 “PDO drivers” 行,确认sqlite在列表中
DSN 路径写错 = 连上了一个空库
SQLite 不是服务,它靠文件路径定位数据库。路径一错,PDO 就自动创建一个全新空白文件,你所有 INSERT 都进了“假库”,自然查不到数据。
- 绝对路径最稳:
sqlite:/var/www/myapp/data/app.db(Linux)或sqlite:C:\inetpub\wwwroot\data\app.db(Windows) - 用
__DIR__拼接更可靠:'sqlite:' . __DIR__ . '/data/app.db',避免因工作目录(getcwd())变化导致路径失效 - 别写
sqlite:./data/app.db或sqlite:data/app.db—— Web 服务器的工作目录不一定是你的脚本所在目录 - 检查生成的 .db 文件是否真在预期位置,且大小 > 0 字节
连接后立刻设置错误模式和 WAL 模式
默认的错误模式太安静,SQLSTATE[HY000]: General error 这种报错根本看不出哪错了;而默认的回滚日志机制在并发写入时容易卡住。
立即学习“PHP免费学习笔记(深入)”;
- 必须加这两句:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)和$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false) - 捕获异常后,用
$pdo->errorCode()和$pdo->errorInfo()拿到 SQLite 原生错误码和消息,比如SQLITE_BUSY或SQLITE_ERROR: no such table - 高并发场景下,连接后马上执行:
$pdo->exec("PRAGMA journal_mode = WAL"),再查$pdo->query("PRAGMA journal_mode")->fetchColumn()确认返回wal - WAL 模式要求
-wal和-shm文件与主库在同一文件系统,跨挂载点会静默退回到 DELETE 模式
INSERT/SELECT 必须用预处理防注入,别拼字符串
SQLite 对 SQL 注入一样敏感,而且字段名含空格、短横线或关键字时,不加引号直接报错。
- 用
prepare()+bindValue()是底线:$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); $stmt->bindValue(1, $name); $stmt->bindValue(2, $email); $stmt->execute(); - 字段名或表名含特殊字符时,用双引号或方括号包裹:
SELECT "user-name", [order] FROM "my-table" - 不要用
mysql_real_escape_string那套——PDO 预处理才是唯一靠谱的防注入方式 -
exec()只适合 DDL(如CREATE TABLE)或无参数的 DML,带变量一律走prepare()
路径、权限、错误模式这三项没调对,后面所有 SQL 写得再漂亮也白搭。尤其是 errorInfo() 和 journal_mode,线上出问题时翻日志第一眼就该盯这两个。



















