PHP会话在超时后登录时未重置

PHP会话在超时后登录时未重置,php,session,Php,Session,我在每页的顶部都有以下代码: 来自“PROCESS-LOGIN.PHP” 来自“SESSION.PHP” 在某些页面的顶部,我检查$membertype,下面是该代码的示例: if ($membertype != 99){ die("You're session has timed out. Please <a href='/view/login.php'>login again</a>"); } if($membertype!=99){ die(“您的会话已超

我在每页的顶部都有以下代码:

来自“PROCESS-LOGIN.PHP”

来自“SESSION.PHP”

在某些页面的顶部,我检查$membertype,下面是该代码的示例:

if ($membertype != 99){
    die("You're session has timed out. Please <a href='/view/login.php'>login again</a>");
}
if($membertype!=99){
die(“您的会话已超时。请”);
}
如果我登录到web应用程序,我会通过上面的检查进入页面,一切正常。如果我几个小时后回来,就会收到“您的会话已超时”消息。如果我输出变量,它会将$membertype显示为“xxx”-这是在未设置$\u会话['id']时设置的

到目前为止,对我来说,这一切都是有道理的


让我困惑的是,如果我登录,$membertype仍然是“xxx”,并且该页面仍然失败。

您的代码存在许多问题。它可能有效(或无效),但不符合最佳实践,因此像这样的错误会突然出现,很难消除

1) 您的错误日志告诉您什么? 存储日志的位置,并将其用于输出

2) 停止使用isset() 坦白地说,这是一个糟糕的函数,因为对于那些不习惯PHP怪癖的人来说,它的返回值并不总是合乎逻辑的。不要用它。我觉得
empty()
在判断变量值时给出了更准确的结果

更好的是,尽可能具体。如果
$\u SESSION['id']
将是一个数值,您只需执行以下操作:

if((int)$_SESSION['id'] > 0 ){
    //stuff happens when a positive value of id is found.
} 
说明:
(int)
将值强制转换为整数,然后将其与大于零的值进行比较。因此,
false
null
值在变为
0
时决不是误报。而
isset
将为
值返回
true

3) 清理你多余的
。
在任何情况下,
}
之后都不需要它们

4) 你查错密码了。 你应该使用。您应该检查数据库中的用户名,
选择
ing对应的[hash]密码,然后检查该值是否与
POST
ed输入的哈希值匹配。为什么?

解决这个问题。没有借口。这需要修复。

5) 停止将字符串变量包装在括号中。 它是不需要的,并且可能会导致处理函数(应该有括号)问题的逻辑问题,以及为其他人阅读代码时的混乱

6) 多次检查同一值时,请使用
开关
语句。 这比一堆
if
语句更有效,因为您只需检查一次,然后查看结果是否匹配

switch ($membertype){
    case 1:
        $home = "/view/cook-dashboard.php";
        break;
    case 2:
        $home = "/view/customer-dashboard.php";
        break;
    case 3:
        $home = "/view/admin/dashboard.php";   
        break;
    default:
        $membertype = "xxx"; 
        $userID = 0;
   }
7) 停止创建浪费的变量。 您已经创建了
$userID
变量,但它与$\u SESSION['ID']值完全相同,所以它有什么意义?它可能为您的编码风格增添了整洁,但您的
else
值只会重置变量,而不会重置会话

当然,如果您到达
else
,则需要将
$\u会话['ID']=0也是吗

多余的和重复的变量是

8) 研究在MySQLi中使用准备好的语句 网上有很多关于使用预先准备好的语句的信息。探索它。还有一个关于如何使用准备好的语句的例子

9) 停止使用
选择*
特别挑选合适的人选。节省能源,节省时间

10) 检查你的数据库!
  • 您的列名正确吗?名称区分大小写
  • 同一行中的其他数据是否返回正常
  • 该特定字段中是否有要返回的数据
最后。。。。。。 11) 你的问题需要探讨。 试试这个:

while ($db_result = mysqli_fetch_assoc($login_result))
    {
    error_log("While loop run. Login Data found:\n");
    error_log(print_r($_db_result,true));

    $id = $db_result['id'];
    $membertype = $db_result['memberType'];
    ....
这将准确地告诉您列
memberType
是否具有所选行的值


从您显示的代码中,我怀疑a)过量的
导致逻辑中断。或者b)数据库数据未按预期输出



免责声明:还有其他一些小错误和症状性问题,但我必须在某处划清界限。。。。此外,我分享的许多最佳实践也有一些不适用的具体情况

您在哪里设置会话值
$\u session['id']
?检查ini文件和缓存,以及会话是否在所有文件中启动,同时检查会话数组是否确实已设置/不为空。很抱歉,我将重写您的整个代码库。为什么把变量用括号括起来?为什么要使用
选择*
?你为什么要用
追踪所有东西?等等@Martin代码库将被完全重写。这是一个原型。我可以编程,并编写相当广泛的功能性应用程序,但我不会称自己为软件开发人员。我知道我有不好的做法,我的代码不是最好的。当需要真正编写这个应用程序时,如果它被证明是有价值的,那么我会有真正的开发人员来做。有更多的代码在上面吗?我看到了一个数据库查询,但没有连接到数据库的代码……我将继续学习。说真的,非常感谢你花时间指出这些事情。我将百分之百地在这里学习未来的课程。我确实想让你知道我正在散列密码@马丁
switch ($membertype){
    case 1:
        $home = "/view/cook-dashboard.php";
        break;
    case 2:
        $home = "/view/customer-dashboard.php";
        break;
    case 3:
        $home = "/view/admin/dashboard.php";   
        break;
    default:
        $membertype = "xxx"; 
        $userID = 0;
   }
while ($db_result = mysqli_fetch_assoc($login_result))
    {
    error_log("While loop run. Login Data found:\n");
    error_log(print_r($_db_result,true));

    $id = $db_result['id'];
    $membertype = $db_result['memberType'];
    ....