超时后,PHP会话不会在登录时重置

时间:2018-01-13 14:28:59

标签: php session

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

FROM“PROCESS-LOGIN.PHP”

session_start();


$login_query
    = ("select * from members where email = '$email' and  password = '$password'");
$login_result = mysqli_query($link, $login_query);
$hits = mysqli_affected_rows($link);

if ($hits != 1)
{
    echo "Invalid username and password combination ";
};

while ($db_result = mysqli_fetch_assoc($login_result))
{
    ;
    $id = $db_result['id'];
    $membertype = $db_result['memberType'];

    $_SESSION['id'] = $id;

FROM“SESSION.PHP”

session_start();
if ( isset($_SESSION['id'])) {
    $userID = $_SESSION['id'];

    $session_query = ("select * from members where id = '$userID'");
    $session_result = mysqli_query($link, $session_query);

    while ($db_result = mysqli_fetch_assoc($session_result)) {

        $email = $db_result['email'];
        $membertype = $db_result['memberType'];

        // various other things set from the DB

    };

    if ($membertype == 1){
        $home = "/view/cook-dashboard.php";
    } else if ($membertype == 2) {
        $home = "/view/customer-dashboard.php";
    } else if ($membertype == 3) {
        $home = "/view/admin/dashboard.php";
    };


} else {$membertype = "xxx"; $userID = 0;};

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

if ($membertype != 99){
    die("You're session has timed out. Please <a href='/view/login.php'>login again</a>");
}

如果我登录到网络应用程序,我将被带到上面检查的页面,一切都很好。如果我几个小时后回来,那么我会收到“你的会话已经超时”的消息。如果我输出变量,则显示$ membertype为“xxx” - 如果未设置$ _SESSION ['id'],则设置为

到目前为止,对我而言,这一切都是有道理的。

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

1 个答案:

答案 0 :(得分:1)

您的代码存在许多问题。它可能有效(或没有),但没有达到最佳做法,因此这样的错误会突然出现并且难以消除。

1)您的错误日志告诉您什么?

存储日志的

find out here,并将其与error_log一起使用,以输出custom messages

2)停止使用isset()

坦率地说,isset()是一个糟糕的功能,因为对于那些不熟悉PHP怪癖的人而言,它的返回值并不总是合乎逻辑的。不要使用它。我觉得empty()在判断变量的值时会给出更准确的结果。

更好,尽可能具体。如果$_SESSION['id']将是一个数值,您只需执行此操作:

if((int)$_SESSION['id'] > 0 ){
    //stuff happens when a positive value of id is found.
} 

说明:
(int)将值转换为整数,然后比较它是否大于零。因此, false null 值永远不会为误报,因为它们会变为0。而isset会为 true 值返回 false

3)清理多余的;

在任何情况下}后都不需要它们。

4)您正在检查密码错误。

您应该使用password_hash()。您应该检查数据库中的用户名,SELECT相应的[哈希]密码,然后检查此值是否与POST输入的哈希匹配password_verify()。为什么use password_hash

解决此问题。没有理由。这个需要修复。

5)停止将字符串变量包装在括号中。

它不是必需的,并且可能导致处理函数(应该有括号)问题的逻辑问题以及混淆读取其他代码。

6)多次检查相同的值时,请使用switch语句。

这比一堆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变量,但它与$ _SESSION [&#39; ID&#39;]值相同,那么它的重点是什么?它可以为您的编码风格添加一个整洁,但您的else值只会重置变量,而不会重置会话。

当然,如果您到达else,那么您还需要设置$_SESSION['ID'] = 0;吗?

过量和重复变量为wasted space, processing power and memory

8)研究如何在MySQLi

中使用Prepared Statements

网上有很多关于使用预备语句的almost decent tutorials。探索它。关于如何使用预备语句,还有一个lot of questions on Stack Overflow

9)停止使用SELECT *

专门选择columns you need。节省能源,节省时间。

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)您没有按预期输出数据库数据。

免责声明:还有一些其他更小的错误和症状问题,但我必须在某个地方划清界限......我分享的许多最佳实践都有特定情况他们可能不适用。