PDO:查询第一次没有产生正确的结果

时间:2018-01-15 21:20:31

标签: php pdo

我的登录脚本有三个查询。一个选择查询检查用户'凭证,另一个用于更新上次登录,第三个是选择查询以查看用户是否存在于另一个表中,因此如果用户存在于表中,请转到某个位置。如果用户不存在,请转到其他地方。

第三个问题是一个人表现得很奇怪。下面:

require_once '../includes/sessions.php';
//echo 'hello';
$employerlogindata = $_POST['employerlogindata'];

$data = json_decode($employerlogindata);

$employeremailfromjs = $data->employeremail;
$employerpasswordfromjs = $data->employerpassword;

//sanitization 
$employeremail = htmlentities($employeremailfromjs);
$employerpassword = htmlentities($employerpasswordfromjs);

//PHP validation rules 

$validflag = true;

function checkblanks($variable){
    if($variable == ''){
        $validflag = false;
        print_r('Empty Inputs.  Please try again.');
    }else {
        $variable = trim($variable);
        $variable = stripslashes($variable);
        return $variable;
    }
}
checkblanks($employeremail);
checkblanks($employerpassword);

if($validflag == false) {
 echo 'You have problematic entries.  Try again.';
} else {
    try{
        $sql = "SELECT EID AS dbeid, EMPLOYER_EMAIL AS dbemail, `PASSWORD` AS dbpwd, EMPLOYER_NAME AS dbcompanyname, LAST_LOGIN AS dblastlogin FROM userpwd WHERE EMPLOYER_EMAIL = :employeremail;";

        $query = $conn->prepare($sql);
        $query->bindParam(":employeremail", $employeremail);
        $query->execute(); 
        //echo "select statement successfully executed";
        //echo $sql;
    } catch(PDOException $e){
        echo "Error connecting to server: " . $e->getMessage();
        die;
    }
    //echo $query->rowCount();
    if ($query->rowCount() == 0){
        echo "Email/Password combo was not found in the system.";
    }else {
        $result = $query->fetch(PDO::FETCH_OBJ);
        //print_r($result);

        $dbeid = $result->dbeid;
        $dbemail = $result->dbemail;
        $dbpwd = $result->dbpwd;
        $dbcompanyname = $result->dbcompanyname;
        $dblastlogin = $result->dblastlogin;

        //echo $dbeid;

        if(password_verify($employerpassword, $dbpwd)){
            try{
                $sql = "UPDATE userpwd SET LAST_LOGIN = NOW() WHERE EMPLOYER_EMAIL = :employeremail; ";
                $query = $conn->prepare($sql);
                $query->bindParam(":employeremail", $employeremail);
                $query->execute();

            }catch (PDOException $e){
                echo "Error connecting to server: " . $e->getMessage();
                die;
            }

            $_SESSION['EID'] = $dbeid;
            $_SESSION['EMPLOYER_EMAIL'] = $dbemail;
            $_SESSION['EMPLOYER_NAME'] = $dbcompanyname;
            $_SESSION['LAST_LOGIN'] = $dblastlogin;

            //echo "Logged in";             
        } else {
            echo "Email/Password combination is invalid. Please Try Again.";
        }
        try{
            $select = "SELECT EID from e_profile WHERE EID=:eid";
            $stmt = $conn->prepare($select);
            $stmt->bindParam(":eid", $sessemployerid);

            $stmt->execute();
        }catch(PDOException $e){
            echo "Error connecting to server: " . $e->getMessage();
            die;
        }
        $res = $stmt->fetch();
        $eid = $res['EID'];
        $count = $stmt->rowCount();

        if($stmt->rowCount() == 1){
            echo "employerdashboard.php $eid $count";
            $stmt->closeCursor();
        } else if ($stmt->rowCount() == 0){
            echo "e_profile.php $eid $count";
            $stmt->closeCursor();
        }
    }
}
?>

在一组登录凭据成功后,该脚本将同时发出第二个和第三个查询。但是,第三个查询采用先前运行查询的结果。在使用相同凭据的第二次单击前端后,它会生成正确的结果。

我想也许我可以在PDO的closeCursor中找到mysqli_free_result()的功能,但这并不起作用。我想让它第一次产生正确的结果。

有关为何发生这种情况的任何线索?

1 个答案:

答案 0 :(得分:0)

正如我在评论中所说,你的变量已经过时(或者至少是我的理论)。

如果你有

 global $sessemployerid = $_SESSION['EID'];

然后你做

 $_SESSION['EID'] = $dbeid;

然后您使用$sessemployerid它将不等于$_SESSION['EID'] = $dbeid。它将等于分配时的会话的先前值,这可能是也可能不正确。可能在第一次尝试时它是错误的,然后在随后的尝试中它是正确的。

只是进一步说明:

//you assign $sessemployerid way up here
global $sessemployerid = $_SESSION['EID'];
...
//then you update the session
if(password_verify($employerpassword, $dbpwd)){
    try{
        $sql = "UPDATE userpwd SET LAST_LOGIN = NOW() WHERE EMPLOYER_EMAIL = :employeremail; ";
        $query = $conn->prepare($sql);
        $query->bindParam(":employeremail", $employeremail);
        $query->execute();

    }catch (PDOException $e){
        echo "Error connecting to server: " . $e->getMessage();
        die;
    }

    $_SESSION['EID'] = $dbeid;  //<--- here you update the session but neglect $sessemployerid
    $_SESSION['EMPLOYER_EMAIL'] = $dbemail;
    $_SESSION['EMPLOYER_NAME'] = $dbcompanyname;
    $_SESSION['LAST_LOGIN'] = $dblastlogin;

    //echo "Logged in";             
} else {

 ....

 //then you use $sessemployerid, but it has a stale value (sometimes)
 $select = "SELECT EID from e_profile WHERE EID=:eid";
 $stmt = $conn->prepare($select);
 $stmt->bindParam(":eid", $sessemployerid);

要解决此问题,您可以使用参考作业

global $sessemployerid =& $_SESSION['EID'];

这可以通过这个简单的代码来证明:

 $a = 1;
 $b =& $a;  //initial assignment, with reference  
 echo $b."\n";   
 $a = 2;  //change the value of $a

 echo $b;  //$b is auto-magically updated

here

OUPUTS

1
2

如果你这样做(“正常”方式)

 $a = 1;
 $b = $a;  //initial assignment, normal
 echo $b."\n";   
 $a = 2;  //change the value of $a

 echo $b;  //$b is not updated

输出

1
1

或者,您可以在更改会话值后更新全局:

if(password_verify($employerpassword, $dbpwd)){
    ...
    $_SESSION['LAST_LOGIN'] = $dblastlogin;
    global $sessemployerid = $_SESSION['EID'];
}else{
   ...

由于$sessemployerid的值与$_SESSION['EID']不同步,因此您将获得不一致的行为,具体取决于您是否更新了会话或未尝试上一次尝试。

希望这是有道理的。