php if语句随机失败


php if statement random failure

我正在为我的网站创建一个电子邮件激活页面,但遇到了问题。看起来,尽管页面收到了显示成功激活消息所需的所有信息,但它还是随机决定显示错误消息,说明凭据与数据库中的任何内容都不匹配。这是代码

 // Check their credentials against the database
  try {
    $check = $db->prepare("SELECT * FROM users WHERE id= ? AND username = ? AND email = ? AND user_ident = ? AND activated = '1' AND email_activated = '0' LIMIT 1");
    $check->bindParam(1, $id);
    $check->bindParam(2, $u);
    $check->bindParam(3, $e);
    $check->bindParam(4, $p);
    $check->execute();
    $num_rows = $check->rowCount();
} catch(Exception $er){
    // ERROR : COULD NOT INSERT EMAIL INTO USERS TABLE
    Send_email('support@site.com', 'check user - email activation failure', 'Could not check user '.$er);   
    exit;
}
// Evaluate for a match in the system (0 = no match, 1 = match)
if($num_rows === 0){
    Send_email('support@site.com', 'email activation credentials no match', 'invalid email activation variables.<br/> email: '.$e.'<br/>userid: '.$id.'<br/>username: '.$u.'<br/>user_ident: '.$p); 
    header("location: message.php?msg=Your credentials are not matching anything in our system");
    exit();
}
// Match was found, you can activate them
try {
    $checking = $db->prepare("UPDATE users SET email_activated = 1 WHERE id= ? LIMIT 1");
    $checking->bindParam(1, $id);
    $checking->execute();
} catch (Exception $er){
    // ERROR : COULD NOT INSERT EMAIL INTO USERS TABLE
    Send_email('support@site.com', 'Email add error', 'Could not set active state '.$er);   
    exit;
}

因此,有时,当点击电子邮件中的激活链接时,它会正常工作,而其他时候,它会弹出错误,说凭据与数据库中的任何内容都不匹配。但是,当我在点击链接后立即检查数据库时,email_activated字段已更新,以显示它已被激活。从技术上讲,这不应该发生,因为如果我做得正确,页面将在抛出凭据错误后退出,这意味着email_activated更新代码甚至不应该运行。看起来它可能跑了两次,但我用了一个计数器,它只显示了一次。任何帮助都会很棒!

可能是浏览器正在缓存重定向。尝试明确指定这是"302找到"重定向。

header('HTTP/1.1 302 Found');
header('Location: /your-location');

或者按照您的建议包括所有缓存头:

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT'); 
header('Cache-Control: no-store, no-cache, must-revalidate'); 
header('Cache-Control: post-check=0, pre-check=0', FALSE); 
header('Pragma: no-cache');

好吧,在第一个查询中有更多的过滤器。即:

id= ? AND username = ? AND email = ? AND user_ident = ? AND activated = '1' AND email_activated = '0' 

而你只有一个在第二:

id= ?

如果查询完全不同,则不能期望得到相同的结果。第一个查询中的一个项显然不匹配,但由于第二个查询忽略了除"id"之外的所有项,所以它会继续并更新行。

PDO rowCount不适合您的目的。检查-http://php.net/manual/en/pdostatement.rowcount.php

"PDOStatement::rowCount()返回受相应PDOStatement对象执行的最后一个DELETE、INSERT或UPDATE语句影响的行数。

如果关联的PDOStatement执行的最后一条SQL语句是SELECT语句,则某些数据库可能会返回该语句返回的行数。然而,并非所有数据库都能保证这种行为,便携式应用程序不应依赖这种行为。"

请参阅这个SO问题,以便更好地理解场景。