【问题标题】:PHP - Session lost/emptied on form postPHP - 表单发布时会话丢失/清空
【发布时间】:2012-04-01 14:48:37
【问题描述】:

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

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

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

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

index.php(部分)

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(部分)

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;
}

}

【问题讨论】:

  • 不看代码就很难判断...
  • 我懒惰/累了,以为我可以得到一个简单的答案,对不起,代码已经启动。抱歉,缺少 cmets 等,我对此很陌生。
  • $database-&gt;clearUserSession() 是做什么的?
  • 它删除保存会话ID(用于身份验证)的数据库行。我还没有在变量/方法命名上做出最好的决定,呵呵。
  • 好像是表单提交的时候session ID变了?

标签: php forms session post


【解决方案1】:

在每个你想使用会话的页面中你必须调用session_start();

【讨论】:

    【解决方案2】:

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

    请改用 index.php 页面顶部的session_start();

    【讨论】:

    • 感谢提示好友,不幸的是它没有解决问题:(。我已经编辑了问题,指出一旦用户重新登录,问题就不再存在;我已经还包括一个测试 URL,您可以在其中查看页面顶部的会话数据。
    【解决方案3】:

    看这里:

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

    注意:如果当前用户的密码正在更新,那么cookies 将被清除!

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

    有些人发现在设置密码时在重定向后立即应用exit(); 可以防止cookie 丢失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-15
      • 2013-08-10
      • 2012-05-09
      • 2012-06-03
      相关资源
      最近更新 更多