PHP 中增加会话变量的问题。它只增加一次

Problem with incrementing Session Variables in PHP. It only increments once

我有一个测验 game/guessing 游戏网站,我正在尝试移动记分服务器端的所有代码以阻止人们作弊。游戏向用户显示 2 张图片,用户必须点击正确的一张。

我有 1 个 PHP 包含所有图片 ID。其中 2 个被设置为会话变量并通过 HTTP 请求提供给 Javascript 并放在 html.

所以现在当用户回答问题时,我有 1 个 php 文档用于每个可点击的图像,将图像与解决方案进行比较,并 returns 正确或错误。它还会跟踪分数。之后第一个 php 使用 2 个新的 pictureIDS 调用。

对于分数跟踪,我有会话变量。 “score”变量和“Lives”变量作为 PHP 中的 SESSION 变量,当用户正确或错误时,它们会递增和递减。 (我还有一个连续变量,它在连续三个正确后增加了 2 倍乘数,但这不应该是相关的。)

由于某些原因,分数递增只有效一次。第一个问题得分上升 1 或生命下降 1,但之后每个其他问题得分保持不变。

我已经包含了很多我的代码我希望这不会太过分。基本上 javascript 没有那么重要。您只需要知道我基本上是 运行 第一个 php 然后是第二个,然后是第一个,依此类推。而且它只更改会话变量一次。我究竟做错了什么?我开始会话的方式一定有问题吗? `

PHP 显示选择 2 张图片的文档:


<?php
header('Content-Type: application/json');
?>
<?php
if (session_status() == PHP_SESSION_NONE) {
    session_start();
    $_SESSION["score"]=0;
    $_SESSION["streak"]=0;
    $_SESSION["lives"]=5;
    $_SESSION["onfire"]=0;
}
$rightimages = array( "right1","right2","right3");
$wrongimages = array( "wrong1","wrong2","wrong3");
$right= mt_rand(0,count($right)-1);
$wrong= mt_rand(0,count($wrong)-1);


$coin = mt_rand(0,1);
if ($coin == 1){
    $img1=$rightimages[$right];
    $img2=$wrongimages[$wrong];
    
}else{
    $img1=$wrongimages[$wrong];
    $img2=$rightimages[$right];
}

$_SESSION["im1"]=$img1;
$_SESSION["im2"]=$img2;
$arr = array('im1' => $img1, 'im2' => $img2);

$myJSON = json_encode($arr);

echo $myJSON;
?>

PHP点击img 1时的文档检查解决方法

<?php
header('Content-Type: application/json');
?>
<?php
if (session_status() == PHP_SESSION_NONE) {
    session_start();
    $_SESSION["score"]=0;
    $_SESSION["streak"]=0;
    $_SESSION["lives"]=5;
    $_SESSION["onfire"]=0;
}

$wrongimages = array( "wrong1","wrong2","wrong3");

$iswrong =in_array($_SESSION["im2"], $wrongimages);
if ($iswrong){
    $_SESSION["lives"]--;
    $_SESSION["streak"]=0;
}

if(!$iswrong){
    $_SESSION["score"]++;
    $_SESSION["streak"]++;
    if ($_SESSION["streak"]>2){
        $_SESSION["onfire"]==0;
        $_SESSION["score"]++;
    }
    if ($_SESSION["score"]==10){
        $_SESSION["lives"]++;
}
}
$iswrongnum=(int)$iswrong;
$myarray=array('iswrong' =>$iswrong,'score' => $_SESSION["score"], 'streak' => $_SESSION["streak"], 'lives' =>$_SESSION["lives"]);
$myJSON = json_encode($myarray);
echo $myJSON;
?>

相关JS代码 每道题重复调用此函数。 (我已将其缩减为仅点击图片 1,因为点击图片 2 本质上是相同的,并且与问题无关。)

function play(){
var xmlhttp1 = new XMLHttpRequest();
xmlhttp1.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var myObj = JSON.parse(this.responseText);
    img1 = myObj.im1;
    img2 = myObj.im2;
        document.getElementById("img1").src = img1;
document.getElementById("img2").src = img2;
  }
};
xmlhttp1.open("GET", "arrayquestion1.php", true);
xmlhttp1.send();


document.getElementById("img1").onclick = function() {
    this.onclick=null;
    document.getElementById("img2").onclick =null;
    var xmlhttp2 = new XMLHttpRequest();
        xmlhttp2.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            var myObj2 = JSON.parse(this.responseText);
            isonewrong = myObj2.iswrong;
            score = myObj.score;
            streak =myObj.streak;
            lives =myObj.lives;
  }
};
xmlhttp2.open("GET", "arraynorm1.php", true);
xmlhttp2.send();
}

我明白了!这是可能对其他人有用的答案。

替换开头:

if (session_status() == PHP_SESSION_NONE) {
    session_start();
    $_SESSION["score"]=0;
    $_SESSION["streak"]=0;
    $_SESSION["lives"]=5;
    $_SESSION["onfire"]=0;
}

session_start();
if (!isset($_SESSION['score'])) {
  $_SESSION['score'] = 0;
  $_SESSION['lives'] = 5;
  $_SESSION['streak'] = 0;
  
} 

session_* 函数的背景

从之前回答的评论来看,我觉得这个可以再解释一下;帮助理解发生了什么。

会话函数

session_start

在您的 PHP 脚本中启动会话 它采用 ID(通常来自 cookie)查找相关的存储数据并填充 SESSION 超级全球同资料。

在调用 session_start 之前....

isset($_SESSION) === false;
$_SESSION        === null;
session_id()     === "";
session_status() === 1 === PHP_SESSION_NONE;

sesion_status

检查是否有活动会话(即 session_start 已被调用)和 returns:

int   const                   definition

0 === PHP_SESSION_DISABLED => Sessions are disabled
1 === PHP_SESSION_NONE     => No session loaded
2 === PHP_SESSION_ACTIVE   => Session loaded

请注意,在您的 if 语句中,您可以将适当的 int 值替换为 constant:

if (session_status() === PHP_SESSION_NONE)

// Is the same as...

if (session_status() === 1)

session_id

此gets/setsPPHPSESSIDcookie值(即会话标识符字符串):

  • 设置是否提供参数
    • 必须在session_start
    • 之前调用
  • 如果没有提供参数则获取

例如:

session_id("MyPersonalisedID");
session_start();

// Means...

$_COOKIE["PHPSESSID"] === "MyPersonalisedID";

链接函数

Link, for reference.

首先,请务必注意 function/comment 大约写于 2014 年。

其次,你需要知道 session_status 是在 PHP 5.4 中引入的。

链接函数的作用基本上是:

  • 检查版本
  • 使用版本合适的方法检查会话状态

没有 今天使用该功能的理由。 运行 PHP 小于 5.4 的任何人都不应该 运行 PHP 并且绝对不应该靠近实时站点。

在这种特定情况下,使用该函数会产生相同的错误 - 它只是使用 session_status,因为您的 PHP 版本是 >4。无论如何,如果你愿意,你可以将 session_status()session_id() 交换,它会以相同的方式工作......

if ( session_status() === 1 )

// Is equivalent to...

if ( !session_id() )

你的问题

正如我在原始评论中强调的那样,问题在于这一行...

 if (session_status() == PHP_SESSION_NONE) {

...做一些与您认为不同的事情 [/ want it do]。

该行的作用

检查 session_start 是否已激活。

你怎么想(想?)它做了什么

检查是否存储了用户以前的数据。

你想做什么

是检查变量是否初始化;你可以用你的任何变量来做到这一点:

if (!isset($_SESSION["score"]) )
if (!isset($_SESSION["streak"]) )
if (!isset($_SESSION["lives"]) )
if (!isset($_SESSION["onfire"]) )

或一些组合:

if(!isset(...) || !isset(...))

或者实现一个特定的:

if(!($_SESSION["activeGame] ?? null)) // Set activeGame to `true` once the game starts...
                   

这几乎就是您在其他答案中尝试过的。但是,为了澄清,您需要做的是:

  1. 在脚本开头调用 session_start();。在包含 session 相关数据的任何逻辑之前。
  2. 检查上面的变量以查看它们是否已设置一次会话数据已恢复。