PHP - 在表单上丢失/清空会话

时间:2012-03-16 02:00:05

标签: php forms session post

因此在登录我的网站后调试会话数组后,我发现在发布表单时,所有会话数据都会丢失。调用 updateDetails changePassword 方法时会擦除会话数据。 为什么会这样?

  • 在任何数据处理之前调用session_start()
  • 根据POST请求,会话数据已设置并取消设置(但不是整个$ _SESSION变量)
  • 我使用以下代码检查POST请求:

    if($ _ SERVER ['REQUEST_METHOD'] =='POST'){ }

  • 只发生一次:一旦会话丢失,可以调用这些方法,而不会再出现问题(直到他们通过到期或关闭浏览器而失去会话)。

index.php(part)

session_start();

$page = $_GET['p'];
$query = $_GET['q'];
$req = $_GET['req'];

$user = new User();
switch($page) {
    case 'account':

        if($req=="logout") {
            if($user->isLoggedIn())
                $user->logout();

            header("Location: /?p=account");
            exit();

        }
        else if($req=="signup") {
            if($user->isLoggedIn()) {
                header("Location: /?p=account");
                exit();
            }
            else {

                if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    $form_data = array('username' => $_POST['username'],
                        'password' => $_POST['password'],
                        'password_repeat' => $_POST['password_repeat'],
                        'title' => $_POST['title'],
                        'first_name' => $_POST['first_name'],
                        'surname' => $_POST['surname'],
                        'dob_day' => $_POST['dob_day'],
                        'dob_month' => $_POST['dob_month'],
                        'dob_year' => $_POST['dob_year'],
                        'gender' => $_POST['gender'],
                        'email' => strtolower($_POST['email']),
                        'email_repeat' => strtolower($_POST['email_repeat']));

                    if($user->signup($form_data)) {
                        header("Location: /?p=account");
                        exit();
                    }
                }
            }
        }
        else {
            if($user->isLoggedIn()==true) {                 
                if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    if($req=='editdetails') {

                        $form_data = array(
                            'title' => $_POST['title'],
                            'first_name' => $_POST['first_name'],
                            'surname' => $_POST['surname'],
                            'gender' => $_POST['gender'],
                            'phone' => $_POST['phone'],
                            'email' => strtolower($_POST['email']),
                            'password' => $_POST['password']
                            );

                        if($user->updateDetails($form_data)) {
                            header("Location: /?p=account");
                            exit();
                        }
                    }
                    else if($req=='changepassword') {
                        $form_data = array(
                            'old_password' => $_POST['old_password'],
                            'password' => $_POST['password'],
                            'password_repeat' => $_POST['password_repeat'],
                            );

                        if($user->changePassword($form_data)) {
                            header("Location: /?p=account");
                            exit();
                        }
                    }
                }
                $user->retrieveUserDetails();
                $details=$user->getUserDetails();
            }
            else {
                if($req) {
                    header("Location: /?p=account");
                    exit();
                }
                else if($_SERVER['REQUEST_METHOD'] == 'POST') {

                    $form_data = array('username' => $_POST['username'], 'password' => $_POST['password']);

                    if($user->login($form_data)) {
                        $user->retrieveUserDetails();
                        $details=$user->getUserDetails();
                    }
                }

            }
        }
        break;
}

user.php(part)

class User {

private $auth;
private $details;
private $session_alert;

function User() {

    if(isset($_SESSION['alert'])) 
        $this->session_alert = $_SESSION['alert'];

    $this->auth = isset($_SESSION['auth']) ? $_SESSION['auth'] : null;

    if(isset($this->auth)) {
        $database= new Database;
        if($database->checkUserSession($this->auth['user_id'],session_id())) {
            $this->logged_in=true;
        }
        else {
            $this->addSessionAlert('global','Your login session has possibly timed out, you may login again by <a href="/?p=account">clicking here</a>.',true);
            unset($_SESSION['auth']);
        }
    }
}   

function login($data) {
    $return = false;
    $this->form = new Form($data,0);    

    if(!$this->form->getError()) {
        $database= new Database;
        $error_msg = "The username/password entered was invalid. Please check to see if they are correct and try again, or use the relevant links to recover your account.";

        $salt = $database->getSaltByUsername($data['username']);

        if($salt) {
            $hash = $this->hashpwd($data['password'],$salt);

            // Do login
            $this->auth = array();
            $this->auth['user_id'] = $database->checkUserByHash($data['username'],$hash);

            if($this->auth['user_id']) {
                session_regenerate_id();

                if($database->doLogin($this->auth['user_id'],session_id())) {
                    $details=$database->getUserDetailsById($this->auth['user_id']);
                    $this->auth['first_name'] = $details['first_name'];

                    $_SESSION['auth']=$this->auth;

                    $this->logged_in=true;
                    $return = true;
                }
                else
                    $this->form->pushError('Something went wrong, please try again.');
            }
            else
                $this->form->pushError($error_msg);
        }
        else
            $this->form->pushError($error_msg);
    }
    return $return;
}
function logout() {
    $return = false;

    if(isset($this->auth)) {
        $database= new Database;

        if($database->clearUserSession($this->auth['user_id'],session_id())) {
            unset($_SESSION['auth']);
            $this->logged_in=false;
            session_regenerate_id();
            $return = true;
        }
    }

    return $return;
}
function signup($data) {
    $return = false;
    $this->form = new Form($data,1);    

    if(!$this->form->getError()) {
        $database= new Database;

        if($database->checkUserByUsername($data['username']))
            $this->form->pushError("The username entered already exists, please try again.");

        else if($database->checkUserByEmail($data['email']))
            $this->form->pushError("The e-mail address entered is already in use, please try again.");

        else {
            $dbarray = $data;

            unset($dbarray['password'],$dbarray['password_repeat'],$dbarray['dob_month'],$dbarray['dob_day'],$dbarray['dob_year']);

            $dbarray['dob']=date("Y-m-d", mktime(0,0,0,$data['dob_month'], $data['dob_day'], $data['dob_year']));

            $dbarray['salt']=strtoupper(md5(mt_rand()));
            $dbarray['hash'] = $this->hashpwd($data['password'],$dbarray['salt']);

            // Do signup
            $this->auth = array();
            $this->auth['user_id'] = $database->newUser($dbarray);
            if($this->auth['user_id']) { 
                session_regenerate_id();

                if($database->doLogin($this->auth['user_id'],session_id())) {
                    $details=$database->getUserDetailsById($this->auth['user_id']);
                    $this->auth['first_name'] = $details['first_name'];
                    $_SESSION['auth']=$this->auth;

                    $this->logged_in=true;
                }
                $return=true;
            }
            else {
                $this->form->pushError("Something went wrong, please try again.");
            }
        }
    }
    return $return;
}
function updateDetails($data) {
    $return = false;
    $this->form = new Form($data,2);    

    if(!$this->form->getError()) {
        $database= new Database;

        if( $database->checkUserByEmailNotById($data['email'],$this->auth['user_id']) ) {
            $this->form->pushError("The e-mail address entered is already in use, please try again.");
        }

        else {

            $salt = $database->getSaltById($this->auth['user_id']);
            if($salt) {
                $hash = $this->hashpwd($data['password'],$salt);
                if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
                    $database->updateUserById($this->auth['user_id'],$data);
                    $return = true;

                }
                else 
                    $this->form->pushError("The password entered was incorrect, please try again.");
            }

        }
    }

    return $return;
}

function changePassword($data) {
    $return = false;
    $this->form = new Form($data,3);    

    if(!$this->form->getError()) {
        $database= new Database;

        $salt = $database->getSaltById($this->auth['user_id']);
        if($salt) {

            $hash = $this->hashpwd($data['old_password'],$salt);

            if($database->checkUserIdByHash($this->auth['user_id'],$hash)) {
                $salt=strtoupper(md5(mt_rand()));
                $hash = $this->hashpwd($data['password'],$salt);

                if($database->updateSaltHashById($this->auth['user_id'],$salt,$hash)) $this->addSessionAlert('yourdetails','Your password has been changed successfully.',false);
                $return = true;

            }
            else 
                $this->form->pushError("The old password entered was incorrect, please try again.");
        }
    }

    return $return;
}

function isLoggedIn() {
    return $this->logged_in;
}
function getUserDetails() {
    return $this->details;
}

}

3 个答案:

答案 0 :(得分:2)

在类的构造函数方法中启动会话,听起来不太好。

使用index.php页面顶部的session_start();代替。

答案 1 :(得分:0)

在您要使用会话的每个页面中,您必须调用session_start();

答案 2 :(得分:0)

见这里:

http://codex.wordpress.org/Function_Reference/wp_update_user

  

注意:如果正在更新当前用户的密码,则为cookie   将被清除!

现在,为什么 WordPress会这样做并不清楚,但明确指出,通过wp_update_user()设置密码时,将删除Cookie以及会话。

有些人发现在设置密码后重定向后立即应用exit();会阻止Cookie丢失。