1

I have a quiz game/guessing game website and I am trying to move all the code for scorekeeping serverside in order to stop people from cheating. The game shows the user 2 pictures and the user has to click on the correct one.

I have 1 PHP with all the pictureIDs. 2 of them are set as session variables and are given to the Javascript with an HTTP request and put on the html.

So now when the users answers a question I have 1 php document for each clickable image which compares that image to the solutions and returns correct or false. it also keeps track of the score. After that the first php is called with 2 new pictureIDS.

For the score tracking i have session variables. "score" variable and a "Lives" variable as a SESSION variable in PHP which are incremented and decremented when the user is right or wrong. (I also have a streak variables which adds a 2x multiplier after three correct in a row but that shouldn't be relevant.)

For some reason, the score incrementing only works once. for the first question the score goes up 1 or the lives go down 1 but after that for every other question the score stays the same.

I have included a lot of my code I hope this isn't too overwhelming. Basically the javascript isn't that relevant. All you need to know is I'm basically running the first php then the second, and then the first again and so on in a loop. And its only changing the session Variables once. What am i doing wrong? There must be something wrong with how im starting the session right? `

PHP document for showing selecting the 2 images:


<?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 document checking solution for when img 1 is clicked.

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

Relevant JS code this function is called repeatedly after every question. (i have reduced it down to only clicking image 1 because clicking image 2 would be essentially the same and it's not relevant to the question.)

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();
}
1
  • 1
    This line if (session_status() == PHP_SESSION_NONE) in your code snippets will always evaluate to true. So you reset the values each time. You need to call session_start at the start of your code Commented Feb 11, 2021 at 18:16

2 Answers 2

1

Background on session_* functions

From the comments on the previous answer, I think that this could do with a little further explanation; to help understanding what's going on.

Session Functions

session_start

This starts the session in your PHP script it takes the ID (usually from a cookie) looks up the relevant stored data and populates the SESSION super global with the information.

Before session_start is called....

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

sesion_status

Checks whether there is an active session (i.e. session_start has been called) and returns:

int   const                   definition

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

Note, in your if statements you can swap the appropriate int value for the constant:

if (session_status() === PHP_SESSION_NONE)

// Is the same as...

if (session_status() === 1)

session_id

This gets/sets the PPHPSESSID cookie value (i.e. the session identifier string):

  • Sets if a parameter is supplied
    • Must be called before session_start
  • Gets if no parameter is supplied

For example:

session_id("MyPersonalisedID");
session_start();

// Means...

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

The linked function

Link, for reference.

Firstly, it's important to note that that function/comment was written circa 2014.

Secondly, you need to know that session_status was introduced in PHP 5.4.

What the linked function does is basically:

  • Check the version
  • Use the version appropriate method to check the session status

There is NO reason to use that function today. Anyone who is running PHP on less than 5.4 should not be running PHP and definitely shouldn't be anywhere near a live site.

In this specific case using that function would yield the same error - it simply uses session_status because your PHP version is >4. Regardless, if you wanted to you could swap session_status() with session_id() and it would work in the same way...

if ( session_status() === 1 )

// Is equivalent to...

if ( !session_id() )

Your Problem

As highlighted in my original comment the problem is that this line...

 if (session_status() == PHP_SESSION_NONE) {

...does something different to want you think it does [/ want it to do].

What that line does

Checks to see whether session_start has been activated.

What you think (thought?) it does

Checks to see if there is previous data stored from the user.

What you want to do

Is check to see whether the variables are initialised; you can do that with any of your variables:

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

Or some combination:

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

Or implement a specific one:

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

This is pretty much what you have attempted in your other answer. However, to clarify, what you needed to do was:

  1. Call session_start(); at the beginning of your script. Before any logic which incorporates a session related piece of data.
  2. Check the variables as above to see if they are set once the session data has been restored.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. That is some very helpful background information. That's exctly how I did it.
0

I got it! Here's the answer it might be useful for others.

Replace the beginning:

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

with

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

6 Comments

Glad you figured it out. But I was going to just have you try replacing if (session_status() == PHP_SESSION_NONE) with if (session_status() === PHP_SESSION_NONE) . Note triple equal(=)
Seems like it may be the right way to do it. See the functions contributor notes
@Jamie_D No, that wouldn't work, it would have exactly the same behaviour; PHP_SESSION_NONE is a constant it's value is (int) 1. Before session_start(); is called there is no session and therefore the value of the status function returns 1 | PHP_SESSION_NONE
There's a user contributed function in the function doc that would be useful. See Universal function for checking session status from coder dot ua at gmail dot com
So it seams the session_status() returns different types depending on what version of PHP you're running.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.