1

几个月来,我一直在毫无问题地使用以下代码来跟踪我网站上的唯一会话,但它最近因未知原因停止工作。如果我在单独的文件中测试代码,它会按我最初的预期工作。

代码检查会话是否存在,如果不存在,则创建它并将其设置为 TRUE。然后它执行第二次检查以查看会话是否为 TRUE,然后将其更改为 FALSE 并将命中存储在数据库中。这在每个会话中发生一次。

实现这一点的代码是:

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

当我按预期运行此代码时,无论我刷新页面多少次,输出都不会改变。该'unique_session_id'变量始终不变,因为每个if语句只执行一次。但是,我的生产代码包含这个确切的代码,但突然停止工作。我的生产代码是这样的:

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

正如您所看到的,这段代码是相同的,但是每次我刷新页面时,unique_session_id变量都会发生变化,如果逻辑不受影响,这是不可能的。我唯一的结论是会话在页面刷新之间被删除或丢失。

备注

  • 我正在使用从头开始编写的 MVC 模式。
  • session_start()在任何其他 PHP 行之前被调用 index.php
  • 我尝试移动session_start()到文件中的各个位置,包括在创建会话之前。这无济于事。
  • 我试过使用session_write_close(),它不起作用。

无论发生多少次页面刷新,这两个逻辑语句在每个会话中都应该只执行一次,并且已经以这种方式工作了 2-3 个月。为什么它们在每次页面刷新后突然开始执行?每次页面刷新时逻辑都被评估为 TRUE 的会话变量发生了什么?

编辑

会话问题现已通过从 Web 主机请求新的 php.ini 文件得到修复。

4

2 回答 2

1

您的代码按您编写的方式工作,请查看代码注释。

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
}

但是当 $_SESSION['new_visit'] 为 false 时,这意味着 $_SESSION['new_visit'] 已设置。现在第二次或更多次:

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.

您可以使用unset($_SESSION['new_visit']);,或者如果它仅用于此语句或签入一页,请使用变量,例如$new_visit不使用会话。

于 2013-03-09T22:06:02.767 回答
0

更新:

将此特定会话处理代码保存在一个单独的文件中,您在所有文件的开头都需要该文件。

我注意到你必须至少重新加载一次才能获得会话 ID,而不是你可以这样做,也简化了复杂性:

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'];

我还大胆猜测您没有正确使用 session_start() 并且在您曾经进入的所有文件的开头。一旦你进入一个没有它或使用不正确的页面,事情就会搞砸。


注意:您可以使用

session_destroy();

删除每个设置的会话。你也可以使用

unset($_SESSION['new_visit']);

取消设置某个会话。

于 2013-03-09T22:16:02.740 回答