无法通过php PDO向SQLite数据库插入数据

3

请帮忙看一下问题出在哪里...(我测试了数据库连接是正常的)

<?php
$user_name=$_POST['user_name'];
$password=$_POST['password'];

$dbh=new PDO('sqlite:./db/user.db') or die("fail to connect db");

try{
 $stmt = $dbh->prepare("INSERT INTO user_info VALUES (?, ?)");
 $stmt->bindParam(1, $a);
 $stmt->bindParam(2, $b);
 $a=$user_name;
 $b=$password;
 $stmt->execute();
}
catch(PDOException $e) {echo $e->getMessage();}

?>

抛出的异常信息是什么? - Christian Joudrey
请帮助我们提供帮助。$e->getMessage() 返回任何内容吗? - alexn
什么都没有...这让我发疯 - lkahtz
还有一个和我一样的问题,但是没有得到答案...求助!!(http://stackoverflow.com/questions/2683405/pdosqlite-doesnt-insert-data-yet-no-error) - lkahtz
你的表有主键吗?尝试明确指定你的列,如 INSERT INTO user_info(username, password) VALUES (?, ?) - alexn
为什么我的问题被投票否决了? - lkahtz
4个回答

7
我在与@DerrickCoetzee的评论讨论后重新考虑了这个答案。事实上,这个答案可能是在一些服务器上解决这个问题的唯一方法。我曾建议给数据库通用写入权限,但这显然是不安全的。我发现之所以只能采用这种方法,是因为我的服务器禁止php写入。php无法创建新文件,我也无法将数据库所有者更改为apache或"nobody",没有root访问权限,因此更好的解决方案不可能实现。
实质上,我的服务器锁定了php,只有当每个人都可以写入时,它才能写入。在我看来,这是一个糟糕的服务器设置,导致了这个安全风险,正如@Derrick所建议的那样,sqlite db可能只适用于私人使用或仅限于服务器访问。某些系统无法安全地利用这一点。如果您发现php没有写入访问权限,并且您没有机器的root访问权限,则应考虑联系系统管理员或切换到MySQL(如果可用)。
话虽如此,我认为以下解决方案非常适合快速原型设计解决方案,当db不敏感或仅由少数精选人员知道时。

我的先前回答:

今天我遇到了完全相同的问题!我对php和sqlite还很陌生,但一直在努力。突然间,我遇到了这个巨大的障碍(一整天没有进展),就是无法像问题发布者描述的那样将数据插入我的sqlite数据库。区别在于没有错误消息或异常,只有在将执行语句放入if子句中时返回false。

所以,我最终能够找到一种让插入工作的方法,但我不确定它是否安全。如果您认为有更好的方法,请提供任何评论。

主要问题在于您正在尝试让用户写入您文件系统上的文件。但是,默认情况下,文件夹和文档仅对外部人员具有读取权限。因此,您需要让您的数据库(user.db)及其文件夹(./db)可写入其他人。

因此,您需要进入目录并输入:

chmod 777 ./db
chmod 766 ./db/user.db

这对我解决了问题,希望对您也有所帮助。我不知道是否有更好的方法,但这似乎很合理。


1
除非您的系统上所有用户都是可信的(通常这是一个错误的假设),否则使任何数据库文件具有全局写入权限都非常危险。任何拥有帐户(或已经破坏了任何帐户)的用户都可以轻松地销毁整个数据库。如果确实需要像这样在用户之间共享数据库,则应该使用像MySQL这样的数据库服务器,并使用受限特权的数据库用户。 - Chiara Coetzee
谢谢你提供有关MySQL的提示,但正如问题所问,如何使用sqlite以其他方式完成此操作?我完全理解这种担忧,但是对于sqlite,我个人不知道其他方法。这只是使用sqlite的限制还是有更好的方法? - scicalculator
1
SQLite通常用于数据库仅限于单个用户(例如存储用户的应用程序数据)或通过服务间接访问(例如通过PHP等服务器端Web脚本),在这种情况下,它只需要对服务的特殊用户可用。 - Chiara Coetzee
@DerrickCoetzee 非常感谢讨论。我发现我遇到的主要问题是php根本没有写入权限,而且我无法将apache/php的所有权交给它。我在此解决方案的顶部做了一条注释,说明为什么这样做是不安全的,但对于使用非敏感/安全数据的小规模使用可能是可行的。 - scicalculator
我之前也遇到了同样的问题,原因是sqlite要求它所在的目录也必须可写。你可以将数据库文件放到另一个目录下,例如:db/database.sqlite,然后将“db”目录及其下所有文件的所有者设置为apache(或适用于你的服务器的用户)。具体请参考https://dev59.com/VXM_5IYBdhLWcg3wMgAF。 - Danny Sung
非常感谢您! - Lucas Moraes

0

在定义$a和$b之前,你正在将它们绑定为参数。

$user_name=$_POST['user_name'];
$password=$_POST['password'];
$a=$user_name;
$b=$password;

try{
 $stmt = $dbh->prepare("INSERT INTO user_info (user_name, password) VALUES (?, ?)");
 $stmt->bindParam(1, $a);
 $stmt->bindParam(2, $b);
 $stmt->execute();
}
catch(PDOException $e) {echo $e->getMessage();}

实际上,没有必要先将值分配给 $user_name 和 $password。只需先将它们分配给 $a 和 $b。

[编辑 SQL 以包括列名]


我将代码更改如下: <?php $a=$_POST['user_name']; $b=$_POST['password']; //仍然无法工作... $dbh=new PDO('sqlite:./db/user.db') or die("连接数据库失败");try{ $stmt = $dbh->prepare("INSERT INTO user_info ('user_name', 'password') VALUES(?, ?)"); $stmt->bindParam(1, $a); $stmt->bindParam(2, $b); $stmt->execute(); } catch(PDOException $e) {echo $e->getMessage();}?> - lkahtz
INSERT INTO user_info(username, password) 不是 'username','password' - Christian Joudrey
@Christian Joudrey 是正确的。从列名周围移除引号,然后它就应该工作了。 - David Powers

0

尝试这种方式:

$stmt = $dbh->prepare("INSERT INTO user_info VALUES (?, ?)");
$data = array($user_name, $password);
$stmt->execute($data);

-1

当绑定参数 $a$b 时,两者不存在。

请尝试使用以下代码:

 $stmt->bindParam(1, $user_name);
 $stmt->bindParam(2, $password);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接