XAMPP中PDO使用ATTACH DATABASE跨目录访问SQLite数据库的问题
在XAMPP环境下解决SQLite ATTACH DATABASE路径问题
这个问题我之前也碰到过,核心原因是命令行和网页环境下的PHP工作目录不一样:
- 当你在htdocs目录下用PHP命令行运行脚本时,当前工作目录就是htdocs,所以
../S2.db能正确指向htdocs的上级目录。 - 但通过localhost访问时,Apache进程的工作目录默认是XAMPP的
apache/bin目录(不是htdocs),这时候../S2.db指向的是apache目录,自然找不到你的S2.db文件。
正确的解决方式:使用绝对路径
最可靠的做法是用PHP的内置常量来生成绝对路径,避免相对路径的歧义。推荐两种写法:
方法1:直接用__DIR__拼接路径
__DIR__会返回当前PHP脚本所在的目录,你可以基于它来拼接S2.db的绝对路径,再用PDO的quote()方法转义路径(避免特殊字符导致SQL语法错误):
$db = new PDO('sqlite:S1.db'); // 生成S2.db的绝对路径,假设它在htdocs的上级目录 $s2DbPath = __DIR__ . '/../S2.db'; // 转义路径字符串,确保SQL语法正确 $escapedPath = $db->quote($s2DbPath); // 执行ATTACH命令 $db->exec("ATTACH DATABASE $escapedPath as table1");
方法2:基于主数据库的路径推导
如果你不确定脚本的位置,也可以先获取主数据库(S1.db)的绝对路径,再推导S2.db的位置:
$db = new PDO('sqlite:S1.db'); // 查询主数据库的绝对路径 $stmt = $db->query("PRAGMA database_list"); $mainDbPath = ''; while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { if ($row['name'] === 'main') { $mainDbPath = $row['file']; break; } } // 得到主数据库所在目录,再拼接S2.db的路径 $mainDbDir = dirname($mainDbPath); $s2DbPath = $mainDbDir . '/../S2.db'; $escapedPath = $db->quote($s2DbPath); $db->exec("ATTACH DATABASE $escapedPath as table1");
额外提示
- 如果你需要确认当前PHP环境的工作目录,可以在脚本里加一行
echo getcwd();,分别用命令行和网页访问查看,就能清楚看到差异。 - 确保S2.db所在目录的权限确实允许Apache进程访问(XAMPP下一般给
755权限,文件给644权限即可)。
内容的提问来源于stack exchange,提问作者Stanford Wong
相关产品推荐
相关产品推荐

