2012-04-15 114 views
0

有人可以告诉我,当你prepare()声明(在我的情况下更新声明),然后​​它,然后我检查使用rowCount()后更新查询(见下面的代码)如果rowCount() > 0如果它是然后找到匹配和更新发生了,但是我得到了另一个声明。PHP PDO,需要确保我明白我的代码是什么?

为了确保我不会将自己与语句中的语法错误和条件混淆,我想问下我的代码(详细注释了具体的区域)else语句基本上意味着无法更新,因为匹配不是发现和/或可能的语法错误或一些其他错误?我认为这意味着我大胆表达的意思只是想确保我不会让自己感到困惑。

请在准备语句中忽略SQL UPDATE语法本身,因为它是错误的,将在稍后处理。我认为该代码解释更好,并在我所谈论的领域提供详细的评论。

// check if key is set and alphanumeric and equals 40 chars long 
// we use sha1 so it will always be 40 chars long. 
if(isset($_GET['key']) && ctype_alnum($_GET['key']) && strlen($_GET['key']) == 40){ 
$key = trim($_GET['key']); 
} 

// if key isset and valid 
if(isset($key)){ 


try { 
    // connect to database 
    $dbh = sql_con(); 

    // checke if activation key matches and user_uid matches 
    $stmt = $dbh->prepare(" 
      SELECT 
       users_status.user_uid, 
       users_status.user_activation_key 
      FROM 
       users_status 
      JOIN 
       users 
      ON 
       users_status.user_activation_key = ? 
      AND 
       users_status.user_uid = users.user_uid LIMIT 1"); 

    // execute query 
    $stmt->execute(array($key)); 

    // if row count greater than 0 then match found 
    if ($stmt->rowCount() > 0) { 

     // user verified; we now must update users status in users table to active = 1 
     // and set the user_activation_key in the users_status to NULL 
     $stmt = $dbh->prepare(" 
      UPDATE 
       users.user_status, 
       users_status.user_activation_key 
      SET 
       user_status = ".USER_STATUS_ACTIVE.", 
       user_activation_key = NULL 
      JOIN 
       users 
      ON 
       users_status.user_activation_key = ? 
      AND 
       users_status.user_uid = users.user_uid LIMIT 1"); 

     // execute query 
     $stmt->execute(array($key)); 

     if ($stmt->rowCount() > 0) { 

      echo 'account now activated'; 
      exit; 

     } else { 
      // update not sucessful 
      // THIS IS THE BIT IM CONFUSED WITH; 
      // IF RETURNED RESULT IS 0 (WHICH IT WILL BE IF I GET HERE WHEN RUNNING SCRIPT) 
      // THEN I GUESS THAT MEANS THERE WAS NOT AN ERROR IN SQL SYNTAX BUT 
      // CONDITION IN SQL STATEMENT COULD NOT BE MATCHED ? IS THAT CORRECT WHAT I AM THINKING ? 
      // IF I AM CORRECT THEN OBVIOUSLY I WILL DISPLAY A MESSAGE TO USER AND EXIT HERE; 
      // AS IF I AM THINKING RITE ANY SYNTAX ERROR WOULD BE CAUGHT BY CATCH BLOCK AND THIS ELSE STATEMENT 
      // MEANS COULD NOT UPDATE BECAUSE NO MATCH IN UPDATE QUERY COULD BE FOUND ? 
     } 


    } // else no match found 
    else { 

     // no match found invalid key 
     echo '<h1>Invalid Activation Link</h1>'; 

     $SiteErrorMessages = 
     "Oops! Your account could not be activated. Please recheck the link in your email. 
     The activation link could not be found or the account has already been activated."; 

     SiteErrorMessages(); 

     include($footer_inc); 
     exit; 

    } 

    // close database connection 
    $dbh = null; 

} // if any errors found log them and display friendly message 
catch (PDOException $e) { 
    ExceptionErrorHandler($e); 
    require_once($footer_inc); 
    exit; 
} 

} else { 

// else key not valid or set 
echo '<h1>Invalid Activation Link</h1>'; 

$SiteErrorMessages = 
"Oops! Your account could not be activated. Please recheck the link in your email. 
The activation link appears to be invalid.<br /><br /> 
If the problem persists please request a new one <a href='/member/resend-activation-email'>here</a>."; 

SiteErrorMessages(); 

include($footer_inc); 
exit; 

} 
+2

如果你正在寻求反馈改进工作代码,那么你最好还是问上http://codereview.stackexchange.com/ – GordonM 2012-04-15 10:12:41

+0

不,我不是问我的思维逻辑是否正确。 – PHPLOVER 2012-04-15 10:14:21

+0

'msqls()'做了什么?如果它是任何类型的逃跑,摆脱它。通过使用PDO准备的语句,您不必逃避;实际上,转义会添加额外的反斜杠或引号,而这些反斜杠或引号在数据库中通常不需要。 – ThiefMaster 2012-04-15 10:20:33

回答

1

你是对的:

if $stmt->rowCount() == 0 

那么就意味着没有行已更新。

如果在执行查询您会收到一个假的返回值或者还当你执行

execute(array($key)); 
+0

好的,谢谢,我现在理解'$ stmt-> rowCount()== 0',但是你已经突出显示的执行部分,我是否也应该把它们放在if语句中?因为我认为使用try和catch块,任何错误(如语法错误)都会在catch块中被捕获,并且如果'execute(array($ key));'由于某种原因失败将会被catch块捕获?感谢phplover – PHPLOVER 2012-04-15 10:17:59

+1

把执行放在if-else语句中是一个好主意:if(execute == true)...否则“查询失败”这种方式任何可能的查询failueres不会产生PDO异常管理 – 2012-04-15 11:02:21

+0

好的,谢谢,我认为一个catch块会捕获execute(),如果它失败了,我一定是困惑自己与catch部分什么的。谢谢phplover – PHPLOVER 2012-04-15 11:20:30

1

如果你正在做多个更新一个PDO EXCEPTION HEVE SQL错误或错误,你应该使用的交易。

不过请注意,交易不是在默认的MyISAM引擎支持,所以如果你想要这个工作,你需要ALTER TABLE tbl_name ENGINE=InnoDB

$success = false; 
$dbh->beginTransaction(); 
# perform your first query 
if ($query->rowCount() == 1) { 
    # something was updated/inserted/deleted 
    # perform second query 
    if ($query->rowCount() == 1) { 
     $success = true; 
    } 
} 

if ($success) $dbh->commit(); 
else $dbh->rollBack(); 

至于你的问题,你可能需要围绕你的?用单引号因此改变你的语句是:

users_status.user_activation_key = '?'; 

为什么你可能不会得到结果的另一个原因,是如果你的$键是整数并且使用PreparedStatement::execute($array)方法来绑定您的参数,您需要确保你投值到正确的类型,它的工作,例如:

$query->execute(array((int)$key)); 

否则只是用$query->bindParam($key)

+0

嗨,在这段代码中使用事务不是我想要的,我首先需要确保** users_status **表中的$ _GET ['key']'匹配的激活密钥和user_status中的user_uid匹配表格也匹配** users **表格中的表格。如果找到一个匹配,我会进行更新查询,但如果找不到匹配,那么激活链接显然是无效的。另外,我相信你不会把**?**放在单/双引号中,因为它不是必需的,我可能错了,但是认为你不把它们放在引号中,也不是说我得到了结果,我只是想确保我正确思考 – PHPLOVER 2012-04-15 10:33:16

+0

@PHPLOVER我实际上并不确定单引号,但我听到有人在关于PHP PDO的一些教程的评论中抱怨。只要看看phpMyAdmin中的表格,看看你的SQL语句是否应该找到一个值。噢,就我所知,你正在做的事情是正确的。问题在于PDO对象使查询比旧的my_sql_rubbish更容易读取/遵循,因此可能会让您感到困惑。 – Ozzy 2012-04-15 10:36:22

+0

是的,我认为我很困惑自己当谈到尝试和赶上块(即,当我应该使用它们)混淆自己与例外等。 – PHPLOVER 2012-04-15 10:50:56

相关问题