You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP+SQLite时,跨目录文件如何正确连接数据库?

解决PHP+SQLite文件分散目录后的运行问题

你现在遇到的核心问题其实是文件路径不统一导致的:一方面是require_once的引用路径容易出错,另一方面是SQLite数据库文件会被创建在当前执行脚本的目录下,导致不同目录的脚本操作的不是同一个数据库。下面我一步步帮你调整代码和结构:

先明确当前的文件结构(根据你的代码推断)

  • incDB/(第一目录)
    • testCreate.php
    • testAPI.php
  • actions/(第二目录)
    • insert.php
  • views/(第三目录)
    • select.php

问题1:数据库文件路径混乱

原来的testCreate.php里用$this->open('test.db'),当insert.php或select.php执行时,会在它们所在的目录创建新的test.db,而不是和incDB目录下的数据库统一。所以我们要给数据库指定绝对路径。

修改testCreate.php

<?php
// 定义项目根目录常量:__FILE__是当前文件路径,dirname取到incDB目录,再dirname就是项目根目录
define('PROJECT_ROOT', dirname(dirname(__FILE__)));

class mySqlite extends SQLite3{
    function __construct(){
        // 用根目录拼接数据库路径,确保所有脚本都操作同一个db文件
        $this->open(PROJECT_ROOT . '/test.db');
    }
}
$db = new mySqlite();
$db->exec("CREATE TABLE IF NOT EXISTS `test` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL);" );
?>

问题2:require引用路径错误

不同目录的脚本用相对路径引用时,层级变化容易出错,最好也基于PROJECT_ROOT来引用文件。

修改testAPI.php

<?php
// 直接引用同目录的testCreate.php,或者用PROJECT_ROOT都可以
require_once(dirname(__FILE__) . '/testCreate.php');

function insert($name){
    global $db;
    $stmt = $db->exec("INSERT INTO `test`(`name`) VALUES ('$name')");
    return $stmt !== false;
}

function select(){
    global $db;
    if($stmt = $db->prepare('SELECT id,name FROM test ORDER BY `id` DESC ')) {
        $result = $stmt->execute();
        $names=array();
        while($arr=$result->fetchArray(SQLITE3_ASSOC)) {
            $names[]=$arr;
        }
        return $names;
    }
    return []; // 增加默认返回,避免无数据时出错
}
?>

修改insert.php

<?php
// 定义根目录:当前文件在actions/,dirname两次到项目根
define('PROJECT_ROOT', dirname(dirname(__FILE__)));

if(isset($_POST['new_menu']) && !empty($_POST['new_menu'])){
    require_once(PROJECT_ROOT . '/incDB/testAPI.php');
    $qry = insert($_POST['new_menu']);
    echo $qry ? 'ok' : 'no';
}
?>
<form method='post'>
    <input type="text" name="new_menu">
    <button type="submit">ADD</button>
</form>

修改select.php

<?php
define('PROJECT_ROOT', dirname(dirname(__FILE__)));
require_once(PROJECT_ROOT . '/incDB/testAPI.php');
$rows = select() ?? [];
?>
<table>
<thead>
    <tr> <!-- 补全缺失的tr标签,保证HTML结构规范 -->
        <td style="border: solid 1px #000">id</td>
        <td style="border: solid 1px #000">name</td>
    </tr>
</thead>
<tbody>
<?php foreach($rows as $row){ ?>
<tr>
    <td style="border: dashed 1px #000"><?php echo htmlspecialchars($row['id']); ?></td>
    <td style="border: dashed 1px #000"><?php echo htmlspecialchars($row['name']); ?></td>
</tr>
<?php } ?>
</tbody>
</table>

重要优化:防止SQL注入

原insert函数直接把用户输入拼进SQL,非常危险,改成预处理语句彻底解决风险:

更新testAPI.php里的insert函数

function insert($name){
    global $db;
    // 用预处理语句绑定参数,彻底避免注入
    $stmt = $db->prepare("INSERT INTO `test`(`name`) VALUES (:name)");
    $stmt->bindValue(':name', $name, SQLITE3_TEXT);
    $result = $stmt->execute();
    return $result !== false;
}

这样调整后,不管你的文件放在哪个子目录,只要PROJECT_ROOT定义正确,就能正常引用文件和操作同一个数据库了。

内容的提问来源于stack exchange,提问作者Abdu Hawi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:55:38