如何在 PHP 中调试会话/登录错误


How to debug session/login bugs in PHP?

我试图制作一个简单的登录系统,但我严重卡住了。问题出在会话上。当我按登录时,我被重定向到登录页面。现在据我所知,登录名中启动了一个会话page.session_id()给出了一些数字。

但受保护的页面显示 NULL。如何在受保护的页面上启动会话?我尝试实现一些示例的一些代码 - 仍然重定向到登录页面。我尝试使用新的空页面,只是页面上的表单,但具有相同的数据库,并且仍然重定向到登录页面。

这是登录页面

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require('dbcon.php');
    if (isset($_POST['email']) && ($_POST['password'])) {
        $e = mysqli_real_escape_string($dbcon, $_POST['email']);
        $p = mysqli_real_escape_string($dbcon, $_POST['password']);
        $q = "SELECT uid,mail,psword,unm FROM pics WHERE (mail='$e' AND psword=SHA1('$p'))";
        $result = mysqli_query($dbcon,$q);
            if(mysqli_num_rows($result) == 1){
                session_start();
                $uid = mysqli_fetch_array ($result, MYSQLI_ASSOC);
                $_SESSION['uid'] = $uid['uid'];
                header("location: members.php");
                exit();
                mysqli_free_result($result);
                mysqli_close($dbcon);
            }else{
                echo 'no match';
            }
    }else{
        echo 'Empty fields...';
    }
}
?>

这是在"受保护"页面的顶部

<?php
session_start();
if(!isset($_SESSION['uid'])){
    header("Location:index.php");
}
?>

会话信息

session
Session Support     enabled
Registered save handlers    files user
Registered serializer handlers  php_serialize php php_binary wddx
Directive   Local Value Master Value
session.auto_start  Off Off
session.cache_expire    180 180
session.cache_limiter   nocache nocache
session.cookie_domain   no value    no value
session.cookie_httponly Off Off
session.cookie_lifetime 0   0
session.cookie_path /   /
session.cookie_secure   Off Off
session.entropy_file    no value    no value
session.entropy_length  0   0
session.gc_divisor  1000    1000
session.gc_maxlifetime  1440    1440
session.gc_probability  1   1
session.hash_bits_per_character 5   5
session.hash_function   0   0
session.name    PHPSESSID   PHPSESSID
session.referer_check   no value    no value
session.save_handler    files   files
session.save_path   C:'xampp'tmp    C:'xampp'tmp
session.serialize_handler   php php
session.upload_progress.cleanup On  On
session.upload_progress.enabled On  On
session.upload_progress.freq    1%  1%
session.upload_progress.min_freq    1   1
session.upload_progress.name    PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix  upload_progress_    upload_progress_
session.use_cookies On  On
session.use_only_cookies    On  On
session.use_strict_mode Off Off
session.use_trans_sid   0   0

我所做的假设,这些问题没有说明:

  • 该表单数据以POST类型和正确的字符集提交(因此uuu

  • 问题中显示的所有代码都在标头中引用的文件中,而不是包含在和其他"隐藏的角落"中。

一些代码改进

<?php
session_start(); //at the start.
error_reporting(E_ALL); //as suggested by others add error logging
ini_set('display_errors',1); //and debugging to tell you info. 
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require 'dbcon.php'; //no need for brackets here.
    if (!empty($_POST['email']) && !empty($_POST['password'])) {
        // you had a syntax error here. Also use empty() rather than
        // isset as POSTED forms will still send the data containers
        // even if it contains nothing.
        $e = mysqli_real_escape_string($dbcon, $_POST['email']);
        $p = mysqli_real_escape_string($dbcon, $_POST['password']);
        $q = "SELECT uid,mail,psword,unm FROM pics WHERE mail='$e' AND psword=SHA1('$p')"; //no need for brackets here.
        $result = mysqli_query($dbcon,$q);
            if(mysqli_num_rows($result) == 1){
                $uid = mysqli_fetch_array ($result, MYSQLI_ASSOC);
                if(is_array($uid) && count($uid) > 0){
                    //added a further debug qualifier here 
                    // to check that your SQL result is as expected.
                    $_SESSION['uid'] = $uid['uid'];
                    mysqli_free_result($result); //These occur AFTER the 
                    mysqli_close($dbcon); // exit statement which stops the script. 
                    //so put them before hand. but it's pretty worthless as
                    //mysqli will stop the connection anyway unless 
                    //specifically told otherwise.
                    header("location: members.php");
                     exit();
                      }
                 else {
                  die("your SQL returned an empty result");
                  }
             }else{
                echo 'no match';
            }
    }else{
        echo 'Empty fields...';
    }
}
// removed PHP closing marker.  Unneeded.  

请注意,当您只使用一个值时,为什么从表中选择 4 个值?

目标页面

所以现在你已经向我们保证,这些值正在被 SQL ok 抓取并保存到 SESSION ok,所以问题在于在目标页面上找到会话?

首先,启动会话:

然后,正如其他人所说 - 错误日志和调试:

然后查看传递给会话处理程序的内容:

session_start(); //always at the start!!!
error_reporting(E_ALL); //always use for error reporting in development
ini_set('display_errors',1); //always!!! 
print_r($_SESSION);

如果此处未显示任何错误,则需要返回登录页面并检查会话是否正确保存,因此:

           $uid = mysqli_fetch_array ($result, MYSQLI_ASSOC);
           $_SESSION['uid'] = $uid['uid'];
           $_SESSION['sausages'] = "roasted";
           ...
           header("location: members.php");
           exit();

然后返回查看此静态变量字符串是否出现在您的members.php页面上,

  • 如果是这样,那么这表明您的SQL查询而不是会话无效且失败,我不打算在这里讨论,但足以说明会话不是问题。这里可能的错误是您没有将散列值(SHA1)正确存储在数据库中。但是,我们需要更多信息来提供特定的帮助,以防出现 SQL 错误。

  • 如果没有出现,则确实表明会话问题或文件处理问题,主要是您需要有一个清晰的路径来识别代码是否在文件结构中,您向我们展示的"受保护"页面代码实际上是在标题中引用的页面中,并且此页面是否与登录页面位于同一目录中(而不是任何mod_rewrite jibjag 等)?

告诉我这对确定问题开始的确切位置有什么影响。


在其他说明中,值得注意的是您的密码系统不符合生产质量,应使用不同的方法。请研究StackOverflow。


编辑:

会议详情:

  • session.cookie_httponly转到on
  • 检查文件夹会话是否存储在 ( C:'xampp'tmp 中 ) 中,具有所有读写和执行设置 (chmod 0777 )。
  • session.use_strict_mode更改为on
  • session.auto_start设置为 on

虽然我必须承认,除了绝对确保 PHP 允许读取和写入指定的会话目录之外,您的会话信息中的任何内容对我来说都不是可能的原因。

您的服务器日志(在您的机器上运行 PHP 的程序)上是否有任何错误/警告?

你可以在这里找到一个很好的chmod解释。

这篇文章也可能对你有很大帮助。

这个行标题("位置:成员.php")吗? 工作?

我真的不认为需要以下几行:

exit();
mysqli_free_result($result);
mysqli_close($dbcon);

因为您的页面已被重定向。

现在,您在成员.php页面中到底写了什么?如果我的想法是正确的,您是否在成员.php之上包含此受保护的页面?

我dl html5样板,打开一个新项目,我开始一个接一个地添加html文件。在我开始编码登录之前,我就备份了该网站。然后我复制了 php 代码。然后是 css 和 js 文件。到目前为止,只要我不更改文件夹的名称,登录就可以使用相同的代码进行。我希望它能保持这种状态。感谢您的时间和帮助。我很感激。