php - 无法运行 INSERT 查询,因为 db 已锁定 - SQLite
问题描述
我已经对此进行了两天的故障排除,并且不知所措。
我有这段代码,其中一个 SELECT 查询在一个表中运行,然后如果令牌与数据库中的那个匹配,它将在另一个表上运行一个 INSERT 查询。
SELECT 查询工作得很好,但是,无论我以哪种方式执行 INSERT 查询,它总是会抛出一个 db is locked 错误。
我尝试使用执行 INSERT 查询
- 执行()
- 询问()
- 查询单()
- 准备()/绑定参数()/执行()
了解它也可能没有完成我也尝试过的 SELECT 查询
- 将busyTimeout() 超时设置为5 秒
- 在 SELECT 和 INSERT 查询之间添加 sleep()
- 关闭和重新打开文件
- 在每个函数中使用面向对象并关闭和重新打开文件
代码
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$db = new SQLite3('../grasscar_test.sqlite');
$token = $_POST['token'];
$res = $db->query("SELECT key FROM admin WHERE key = '$token'");
if ($res === FALSE){
echo '{"correct":"no"}';
}
while ($row = $res->fetchArray()){
$key = "{$row['key']}";
if ($key === $token){
//generate token
$cookieog = openssl_random_pseudo_bytes(32);
$cookie = bin2hex($cookieog);
//respond with token
echo '{"correct":"yes","token":"'.$cookie.'"}';
//get expiary time
$expiary = date("Y-m-d H:i:s", strtotime("+30 minutes"));
//add token and expiary date
$insert = $db->exec("INSERT INTO admin_cookie (cookie, expiary) VALUES ('$cookie', '$expiary')"); //This is the line throwing the error
print_r($insert);
}else{
echo '{"correct":"no"}';
}
}
$db->close();
?>
解决方案
警告
您的查询不安全且易受 SQL 注入攻击。请参阅https://www.php.net/manual/en/sqlite3.prepare.php了解如何执行准备好的语句或如何防止 PHP 中的 SQL 注入?. $token
需要绑定,而不是直接放入查询字符串。或者您可以逃避$token
, 但绑定更好的 IMO 并最终得到更清晰的代码 IMO。
选项1
您可以将整体SELECT
放入一个数组中,然后显式关闭打开的连接或光标SELECT
:
while ($row = $res->fetchArray()){
$resultsArray[] = $row;
}
$res->finalize();
foreach ($resultsArray as $row){
// your existing code
}
选项 2:非加密安全随机
如果您不需要将所有内容打印到屏幕上,并且您不需要加密安全的随机性,您也可以将它们全部放入一个查询中。我找不到任何东西可以在 sqlite 中产生加密随机性(在几分钟的搜索中)。
INSERT INTO admin_cookie (cookie, expiary)
SELECT hex(randomblob(32)), datetime('now', '+30 minutes')
附言
- 你可以试试
pdo
。很确定它支持 sqlite,你可能更喜欢这个界面。 - 与其
INSERT
在循环中 ing,不如构建一个VALUES
列表,然后执行一条INSERT
语句。但是,使用绑定参数时会有点痛苦(尽管通过增加占位符的名称并在构建 VALUES 列表时构建绑定数组完全可行) - 您可能确实需要加密安全的随机性,因此选项 2 并不理想。无论如何,我都不是安全专家。
推荐阅读
- r - 为什么我的采样没有节省计算时间?
- vba - Access VBA中Excel图表的SetDataSource
- django - SimpleTestCase 中不允许对“默认”的 Django 数据库查询
- flutter - Dart 中的空安全性
- jira-zephyr - 如何使用 Zephyr ZAPI 获取特定版本的测试周期
- fft - 2D FFT 卷积还是 1D?
- excel - VBA Vlookup 太快而无法解释变量的变化
- javascript - package.json 中的生产脚本找不到模块
- python - 如何将日期字符串传递给 django 中的日期时间字段?
- python - 有没有办法在另一个数据帧的 NaN 的相应位置用一个数据帧的 NaN 替换值