2

我正在尝试在 PHP 中使用 SQLite3,在我需要执行更新之前一切都很好。我想我错过了一个提交,但我没有找到如何去做的方法。

我的代码是:

$respostes = $_POST['respostes'];
$return = array();

$conn = new SQLite3( '/home/pi/boxberry/boxberry.db', SQLITE3_OPEN_READWRITE );

$res = $conn->query( 'SELECT numero, resposta FROM preguntes WHERE NOT correcta' );
while( $resposta = $res->fetchArray( SQLITE3_ASSOC ) )
{
    if( strstr( strtolower( $respostes ), strtolower( $resposta['resposta'] ) ) !== FALSE )
    {
        $conn->exec( 'UPDATE preguntes SET correcta = 1 WHERE numero = ' . $resposta['numero'] );
        $return['canvis'] = $conn->changes();
        $conn->exec( 'COMMIT' );
        $res = $conn->query( 'SELECT correcta FROM preguntes WHERE numero = ' . $resposta['numero'] );
        $tmp = $res->fetchArray( SQLITE3_ASSOC );
        $return['tmp'] = $tmp['correcta'];
    }
}

.... more stuff ...

echo json_encode( $return );

我想要的是从数据库中读取所有问题,并将resposta列中的答案与$respostesPOST 收到的变量中的答案进行比较。这也很好用。然后,如果答案是正确的,我需要把这个正确性放到数据库中,correcta将这一行的列设置为 1。如果我显示查询然后我把它放在 SQLite3 控制台上它可以正常工作,但是当我重新检查它时在 PHP 上它一直为 0,即使$conn->changes()显示 UPDATE 影响了 1 行。

我检查了我能想到的一切,boxberry.db 文件对任何用户都是可读和可写的,我尝试使用默认的 SQLITE3_OPEN_READWRITE 打开它,我尝试添加一个 COMMIT 的执行,甚至将它放在同一个 exec用分号分隔的行...没有引发错误,但值不会改变。

将 SQLite 与 Python 一起使用,我发现我需要在 UPDATE 之后提交,但我找不到在 PHP 中执行此操作的方法。

该脚本返回如下内容: {"canvis":1,"tmp":0} 这意味着它应该是 1 变化,但是当数据库中的值应该是 1 时仍然是 0。

4

2 回答 2

5

我建议为此使用 PDO 而不是 SQLite3 扩展:

$dbh = new PDO('sqlite:/home/pi/boxberry/boxberry.db');

$res = $dbh->query('SELECT numero, resposta FROM preguntes WHERE NOT correcta');
foreach($res as $resposta)
{
  if(FALSE !== strstr(strtolower($respostes), strtolower($resposta['resposta'])))
  {
    $updstmt = $dbh->prepare('UPDATE preguntes SET correcta = 1 WHERE numero = :numero');
    $updstmt->bindParam(':numero', $resposta['numero']);
    $updstmt->execute();
    $return['canvis'] = $updstmt->rowCount();

    $stmt = $dbh->prepare('SELECT correcta FROM preguntes WHERE numero = :numero');
    $stmt->bindParam(':numero', $resposta['numero']);
    $stmt->execute();
    $return['tmp'] = $stmt->fetchAll();
  }
}

这是未经测试的,但应该可以作为 OP 示例代码的替代品。

通过使用 PDO,您不必担心 SQLite 中的提交语句,因为它们是自动处理的。如果您希望能够提交或回滚一组特定的查询,您可以使用PDO::beginTransactionand commit()/ rollBack()

于 2012-08-17T14:49:40.410 回答
4

您不需要使用SQLite3扩展手动提交更改,但您可能需要使包含数据库文件的目录可写(可能设置它以便您的网络服务器软件具有写入权限)。仅仅使数据库文件本身可写对于 SQLite 来说并不总是足够的。

于 2012-08-17T15:10:02.957 回答