在 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 版本是 >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 中增加会话变量的问题。它只增加一次的主要内容,如果未能解决你的问题,请参考以下文章