【问题标题】:Session variable not matching database table variable会话变量与数据库表变量不匹配
【发布时间】:2020-01-21 00:07:45
【问题描述】:

我正在尝试显示此值:$supoints = $_SESSION['upoints'];。但是页面上显示的值与数据库上的值不匹配。

这是我的 index.php 页面:

<?php
session_start();
require 'dbpdo.php';
$sid = $_SESSION['userid'];
$supoints = $_SESSION['upoints'];
?>
<h3>index.php page</h3>
<?php echo $supoints; ?>
<form action="pointshand.php" method="post">
    <input name="buycshamt">
    <button type="submit" name="buyptsbut">Buy</button>
</form>

表单所做的只是将&lt;input name="buycshamt"&gt; 的值提交到我的数据库表列upoints。我的数据库表users 如下所示:

userid | username | upass | upoints
   1   |  user1   | pass1 |  100

它不会匹配,因为当用户第一次登录时,$supoints 的值是 100,但是,当用户为 &lt;input name="buycshamt"&gt; 输入一个新值时,比如300,然后提交,这个新值将在表users 上更新,但不会在变量$supoints 上更新。 $supoints 在网页上将保持为100,但在桌面上它会成功更新为 100+300,等于 400(这是应该在网页上显示的数字. 是什么导致了这种阻​​止更新值的行为 $supoints?

这是我的pointshand.php,它将输入值插入到我的数据库表中:

<?php
session_start();
require 'dbpdo.php';
if(isset($_POST['buyptsbut'])) {
    $buycshamt = $_POST['buycshamt'];
    $sid = $_SESSION['userid'];
    $stmt = $pdo->prepare("UPDATE users2 SET upoints=upoints+? WHERE userid=?");
    $stmt->bindParam(1, $buycshamt);
    $stmt->bindParam(2, $sid);
    $stmt->execute();
    $stmt = null;
    header('Location: index.php'); exit();
}
$pdo = null;
?>

这是我使用会话变量登录用户的 signinhand.php:

<?php
if (isset($_POST['login'])) {
    require 'dbpdo.php';
    $useremail = $_POST['useremail'];
    $password = $_POST['password'];
    if (!empty($useremail) || !empty($password)) {
        $stmt = $pdo->prepare("SELECT userid, username, upoints, upass FROM users2 WHERE username=?");
        $stmt->bindParam(1, $useremail, PDO::PARAM_STR);
        $stmt->execute();
        $rows = $stmt->fetchAll();
        foreach ($rows as $row) {
            $sid = $row['userid'];
            $sname = $row['username'];
            $supoints = $row['upoints'];
            $supass = $row['upass'];
        }
        $stmt = null;
        $pwdCheck = password_verify($password, $supass);
        if ($pwdCheck == true) {
            session_start();
            $_SESSION['userid'] = $row['userid'];
            $_SESSION['username'] = $row['username'];
            $_SESSION['upoints'] = $row['upoints'];
            header("Location: index.php?login=success");
            exit();
        }
    }
}
$pdo = null;
?>

【问题讨论】:

  • 进行更新时,您还需要将新值设置为$_SESSION。为此,您需要选择新值
  • @Phil 我认为会话变量会在更改时自动更新(或在页面刷新后)?那么这行$supoints = $_SESSION['upoints'];不应该在页面刷新后自动更新以反映数据库中的新值吗?
  • 查看您将值分配给$_SESSION['upoints'] 的位置。它只在登录期间发生一次。它不会保持与您的数据库的连接并在数据发生更改时更新。当您处理表单提交和更新数据库时,您还需要分配一个新的会话值,例如$_SESSION['upoints'] = $newValue;
  • @Phil 我还是有点困惑。那么这是否意味着我应该在我的 signinhand.php 页面上的这一行 $_SESSION['upoints'] = $row['upoints']; 之后添加这一行 $_SESSION['upoints'] = $supoints;,还是在我的 index.php 页面上将这一行 $supoints = $_SESSION['upoints']; 更改为这一行 $_SESSION['upoints'] = $supoints;
  • 没有。 当您更新数据库数据时(在 pointshand.php 中)是您将新值分配给会话的时间。 $_SESSION['upoints'] += $buycshamt; 之类的东西,但如果您想更加安全,您可以在 UPDATE 之后查询数据库并从检索到的数据中设置会话值。

标签: php sql session pdo


【解决方案1】:

如果您希望会话中的值与数据库保持同步,则需要同时更新两者。

这将在您处理表单提交和数据库更新的pointshand.php 文件中完成。这最好在事务中完成,以避免数据出现竞争条件。例如

$buycshamt = $_POST['buycshamt'];
$sid = $_SESSION['userid'];
$pdo->beginTransaction();
try {
    $stmt = $pdo->prepare('UPDATE users2 SET upoints = upoints + ? WHERE userid = ?');
    $stmt->bindParam(1, $buycshamt, PDO::PARAM_INT); // make sure it's handled as an int
    $stmt->bindParam(2, $sid);
    $stmt->execute();

    // fetch the updated value
    $stmt = $pdo->prepare('SELECT upoints FROM users2 WHERE userid = ?');
    $stmt->execute([$sid]);
    $_SESSION['upoints'] = $stmt->fetchColumn(); // update the value in the session
    $pdo->commit();

    header('Location: index.php');
    exit();
} catch (PDOException $e) {
    $pdo->rollBack();
    throw $e;
}

【讨论】:

  • 呵呵.. 我认为不需要再次选择会话变量。我一直认为它们会在页面重新加载时自动更新。否则,感谢您修复我的代码并彻底指定在哪里纠正我的错误。非常感谢!
猜你喜欢
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 2015-05-15
相关资源
最近更新 更多