PHP:无法在包含的文件

时间:2017-05-14 14:16:28

标签: php oop session session-variables superglobals

我正在使用PHP中的用户身份验证类,并遇到了会话处理方面的一些问题。

这是基础知识:

  1. global.php我有一个名为global.php的文件,它包含在每个页面加载的开头。从这个文件中我还包括使用的其他类,例如我正在处理的class.uservalidation.php。 我在global.php文件中发起会话。

  2. class.uservalidation.php当在global.php文件的开头实例化此类时,在构造函数中调用checkLogin方法来检查会话变量{{1 }和email如果匹配,则会将hash属性设置为所选用户的级别。

  3. auth是登录页面(显然......),提交时会调用uservalidation类的login.php方法。当成功登录时,此方法将设置两个会话变量loginemail

  4. hash是默认的目标网页,根据登录状态显示不同的内容

  5. 这是一个如何运作的例子:

    我转到index.php。会话启动,类加载实例化。 login.php方法将首先报告checkLogin。我提交表单,然后再次加载相同的页面。在实例化类时,auth=0将首先再次报告checkLogin。然后在auth=0脚本中,我将调用login.php方法并设置会话变量。

    但是...

    我只能从login文件中print_r($_SESSION);而不是login.phpglobal.php看到会话变量(即使这是我设置会话的地方)变量)。

    这是一个问题,因为我需要在后续页面加载时检查class.uservalidation.php方法中的emailhash会话变量。

    由于loginCheck是一个超全球,我认为它可以从任何地方访问,我无法弄清楚出了什么问题......

    我有一种感觉我在这里缺少一些非常基本的东西...我对OOP很新,所以可能是因为我缺少一些关于如何声明变量或其他东西的知识,但因为它是一个超全局我认为没关系。

    [编辑#1]

    这里有一些代码(出于某种原因,我无法粘贴到此文本框中,因此我创建了指向pastebin的链接):

    global.php:

    $_SESSION

    class.uservalidation.php

    <?php
    // Load configuration
    require 'config.php';
    
    // Start secure session
    session_start();
    
    // Include libraries
    require 'class.uservalidation.php';
    
    //Connect to database
    
    // Initialize user validation
    $USER=new Uservalidation();
    
    ?>
    

    的login.php

    <?php
    /*
    --------------------------------------------------------------------------------------
    class.uservalidation.php
    --------------------------------------------------------------------------------------
    Based on example at http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
    
    */
    
    class Uservalidation {
        public function __construct() {
            $this->data=FALSE;
            $this->auth=0;
            $this->loginCheck();
        }
    
        // login function is provided a hashed password directly from the browser (see uservalidation.js)
        public function login($email,$hash) {
            global $DB;
            if($email=filter_var($email,FILTER_VALIDATE_EMAIL)) {
                $email=$DB->real_escape_string($email);
                $hash=$DB->real_escape_string($hash);
                if($user=sql_fetch("SELECT * FROM users WHERE user_email='$email' AND user_hash='$hash' AND user_status>1 LIMIT 1")) {
                    // Successful login
                    $user_browser=$_SERVER['HTTP_USER_AGENT'];
                    $_SESSION['session_email']=$user['user_email'];
                    $_SESSION['session_hash']=hash('sha512',$user['hash'].$user_browser);
                    $this->data=$user;
                    $this->auth=$user['user_auth'];
                    return TRUE;
                } else {
                    // Email and hash does not match
                    // Record attempt in login_attempts table
                    return FALSE;
                }
            } else {
                // Not a valid email address
                return FALSE;
            }
        }
    
        public function logout() {
            $this->destroySession();
            $this->data=FALSE;
            $this->auth=0;
        }
    
        // Validate user session
        private function loginCheck() {
            $user_browser=$_SERVER['HTTP_USER_AGENT'];
            if($user=$this->getUser($_SESSION['session_email'])) {
                $user_hash=hash('sha512',$user['user_hash'].$user_browser);
                if(hash_equals($user_hash,$_SESSION['session_hash'])) {
                    // Successful match
                    $this->data=$user;
                    $this->auth=$user['user_auth'];
                    return TRUE;
                } else {
                    // Hashes does not match
                    return FALSE;
                }
            } else {
                // User doesn't exist
                return FALSE;
            }
        }
    
        // Get data for specific user (either by email, uid or hash)
        public function getUser($string) {
            global $DB;
            //echo "User: $string";
            if($email=filter_var($string,FILTER_VALIDATE_EMAIL)) {
                $checkuser=sql_fetch("SELECT * FROM users WHERE user_email='$email' LIMIT 1");
            } elseif($id=filter_var($string,FILTER_VALIDATE_INT)) {
                $checkuser=sql_fetch("SELECT * FROM users WHERE uid='$id' LIMIT 1");
            } else {
                $hash=$DB->real_escape_string($string);
                $checkuser=sql_fetch("SELECT * FROM users WHERE user_hash='$hash' LIMIT 1");
            }
            return $checkuser;
        }
    
        private function clearSession() {
            // Unset all of the session variables.
            $_SESSION=array();
        }
    
        private function destroySession() {
            $this->clearSession();
    
            // If it's desired to kill the session, also delete the session cookie.
            // Note: This will destroy the session, and not just the session data!
            if(ini_get("session.use_cookies")) {
                $params=session_get_cookie_params();
                setcookie(session_name(), '', time() - 42000,
                    $params["path"], $params["domain"],
                    $params["secure"], $params["httponly"]
                );
            }
    
            // Finally, destroy the session.
            session_destroy();
        }
    }
    ?>
    

1 个答案:

答案 0 :(得分:0)

由于您在评论中停止回答问题,我将采用我的最新想法:

不要在仅php文件中使用关闭?>个php标记。它们倾向于顶部引入被遗忘的空格,这是导致HTML正文在代码中意外发送的原因。

这些空格可能导致在开始会话之前发送标头,这意味着会话cookie变为FUBAR。

另一个可能的原因是,由于global.php,您认为自己的require_once文件未被包含在内。我建议删除_once部分。

无关部分

  

在这篇文章中有很多需要解压缩的内容,所以你得到的是代码评论的“争议流”。

你所拥有的是“包含面向编程”。我强烈建议您了解自动加载器。特别是PSR4自动加载器,附带Composer

使用sha512哈希算法(特别是无盐),是一个非常糟糕的主意。您应该学会使用(相对)新的Password API

用户电子邮件应该已经是唯一参数。在请求帐户详细信息时,没有必要考虑其他WHERELIMIT条件。

当用户登录时,无需在会话中存储登录凭据。您应该只存储帐户ID。

你的类在构造函数中不应该有任何业务逻辑,因为这使得测试所述类非常困难。

你在整个代码库中都有SQL注入。您不应该连接查询中的数据,原因与您在PHP代码中不使用eval()的原因相同。