简体   繁体   中英

Sessions not working as expected

For months I've been using the following code without a problem to track unique sessions on my site, but it has recently just stopped working for an unknown reason. If I test the code in a separate file, it works as I originally intended.

The code checks to see if a session exists, and if not it creates it and sets it to TRUE. It then performs a second check to see whether or not the session is TRUE, whereupon it is changed to FALSE and the hit stored in the database. This happens ONCE per session.

The code to achieve this is:

<?php

session_start();

// If the session DOES NOT EXIST, make it and set it to TRUE.
if(!isset($_SESSION['new_visit']))
{
    $_SESSION['new_visit'] = true;
}

// If the session is TRUE, make it false.
if($_SESSION['new_visit'] == true)
{       
    $_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));

    $_SESSION['new_visit'] = false;
}

echo $_SESSION['unique_session_id'];

When I run this code, as expected, no matter how many times I refresh the page, the output never changes. The 'unique_session_id' variable is always unchanged because each of the if statements are only executed once. However, my production code contains this exact code, but has suddenly stopped working. My production code is this:

<?php

if(empty($article_data))
{
    $no_article = true;
}

$options        = $this->db->get_options();
$server_options = $this->db->server_options();

// Check site status (on/off).
if($options['status'] == "off")
{
    echo $options['offline_message'];

    exit(); // Equal to die.
}

if($server_options['force_ssl'] == "on")
{
    if($_SERVER["HTTPS"] != "on") 
    {
        header("HTTP/1.1 301 Moved Permanently");
        exit(header("Location: https://" . $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"]));
    }
}

$this->db->store_hit();
$this->db->store_ip();

//----------------------------------------------------------------------------------------------------------
// Store visits (individual sessions). Visits are not unique hits. Visits are the number of unique sessions,
// so a single person may accumulate many visits (sessions), i.e., returning users.
//----------------------------------------------------------------------------------------------------------

// If the session DOES NOT EXIST, make it and set it to TRUE.
if(!isset($_SESSION['new_visit']))
{
    $_SESSION['new_visit'] = true;      
}

// If the session is TRUE, make it false.
if($_SESSION['new_visit'] == true)
{
    $this->db->store_visit();

    $_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));

    $_SESSION['new_visit'] = false;
}

?><!DOCTYPE html>
<html>

...

</html>

As you can see this code is identical, yet every time I refresh the page the unique_session_id variable changes, which is impossible if the logic is unaffected. My only conclusion is that the session is being deleted or lost between page refreshes.

Notes :

  • I'm using the MVC pattern which I've written from scratch.
  • session_start() is being called before any other line of PHP in index.php .
  • I've tried moving session_start() to various locations in the file, including right before the sessions are created. This does nothing.
  • I've tried using session_write_close() , it does not work.

The 2 logical statements should only ever be executed once per session no matter how many page refreshes take place, and have been working this way for 2-3 months. Why have they suddenly started executing after every single page refresh? What is happening to my session vars that the logic is being evaluated to TRUE every time the page refreshes?

EDIT

The session issue has now been fixed by requesting a new php.ini file from the web host.

Your code works as you wrote please look at code comments.

if(!isset($_SESSION['new_visit'])) //1st time is not set so enter's to statement
{
    $_SESSION['new_visit'] = true;    //making  $_SESSION['new_visit'] true
}

if($_SESSION['new_visit'] == true) //1st time its true
{
    $this->db->store_visit();
    $_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
    $_SESSION['new_visit'] = false; //You make it false
}

but when $_SESSION['new_visit'] is false, that mean $_SESSION['new_visit'] is set. now second or more times :

if(!isset($_SESSION['new_visit'])) //variable is set, and it will not enter here
{
    $_SESSION['new_visit'] = true; // variable stays false
}

if($_SESSION['new_visit'] == true) //variable is false !!!
{
    $this->db->store_visit();
    $_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
    $_SESSION['new_visit'] = false; 
}
// Finally $_SESSION['unique_session_id'] stays same.

You can use unset($_SESSION['new_visit']); or if it only for this statement or to checking in one page, use variable like $new_visit don't use session for that.

Updated:

Save this specific session handling code in a separate file which you require in the beginning in all of your files.

I noticed that you HAVE TO reload at least once to get a session id, instead you could do this, also simplifying the complexity:

if(!isset($_SESSION['new_visit']))
{
    $_SESSION['new_visit'] = true;
    $_SESSION['unique_session_id'] = hash("sha512", uniqid("", true) . uniqid("", true) . uniqid("", true));
}
echo $_SESSION['unique_session_id'];

I'm also taking a wild guess that you're not using session_start() properly and in the beginning of ALL files which you ever go into. Once you enter a single page that doesn't have it or is using it incorrectly then things screw up.


Note: You can use

session_destroy();

to delete every set session there is. You can also use

unset($_SESSION['new_visit']);

to unset a certain session.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM