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

Posted

技术标签:

【中文标题】在 PHP 中增加会话变量的问题。它只增加一次【英文标题】:Problem with incrementing Session Variables in PHP. It only increments once 【发布时间】:2021-05-15 12:17:56 【问题描述】:

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

我有 1 个带有所有图片 ID 的 php。其中 2 个被设置为会话变量,并通过 HTTP 请求提供给 javascript 并放在 html 上。

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

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

由于某种原因,分数递增只起作用一次。对于第一个问题,分数上升 1 或生命值下降 1,但之后其他问题的分数保持不变。

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

用于显示选择 2 个图像的 PHP 文档:


<?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;
?>

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

<?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();

【问题讨论】:

代码 sn-ps 中的这一行 if (session_status() == PHP_SESSION_NONE) 将始终计算为 true。因此,您每次都重置这些值。您需要在代码开头调用session_start 【参考方案1】:

session_* 函数的背景

从上一个答案的 cmets 来看,我认为这可以做一些进一步的解释;帮助了解正在发生的事情。

会话函数

session_start

在您的 PHP 脚本中启动会话,它获取 ID(通常来自 cookie)查找相关的存储数据并使用信息填充 SESSION 超级全局。

session_start 被调用之前......

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

会话状态

检查是否存在活动会话(即session_start已被调用)并返回:

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

这将获取/设置PPHPSESSID cookie 值(即会话标识符字符串):

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

例如:

session_id("MyPersonalisedID");
session_start();

// Means...

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

链接函数

Link, for reference.

首先,重要的是要注意该函数/评论是在 2014 年左右编写的。

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

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

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

今天有没有理由使用该功能。任何在5.4 上运行 PHP 的人都不应该运行 PHP,而且绝对不应该在实时站点附近。

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

if ( session_status() === 1 )

// Is equivalent to...

if ( !session_id() )

你的问题

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

 if (session_status() == PHP_SESSION_NONE) 

...做了一些不同的事情,希望你认为它确实[/希望它这样做]。

那行的作用

检查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...
                   

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

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

【讨论】:

谢谢。这是一些非常有用的背景信息。我就是这样做的。【参考方案2】:

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

替换开头:

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;
  
 

【讨论】:

很高兴你知道了。但我打算让你尝试用 if (session_status() === PHP_SESSION_NONE) 替换 if (session_status() == PHP_SESSION_NONE) 。注意三等号(=) 似乎这可能是正确的方法。见函数contributor notes @Jamie_D 不,那行不通,它的行为完全相同; PHP_SESSION_NONE 是一个常数,它的值是 (int) 1。在调用session_start(); 之前没有session,因此状态函数的值返回1 | PHP_SESSION_NONE function doc 中有一个用户贡献的函数会很有用。请参阅 用于检查会话状态的通用功能,来自 gmail dot com 上的 coder dot ua 所以它接缝 session_status() 根据你运行的 PHP 版本返回不同的类型。

以上是关于在 PHP 中增加会话变量的问题。它只增加一次的主要内容,如果未能解决你的问题,请参考以下文章

清除 UIWebview 缓存

对于 let,如果数组中有相同的项,则不递增

如何在游戏循环中只检测一次碰撞而不是连续检测碰撞?

ECC原理是啥?

如何在mysql或phpmyadmin中将列的值增加1?

如果多次检查正确的radiobutton,则停止分数增加