0

下面的代码表明我尝试使用代码中给出的标准来找出是否存在一行。它默认为 else 语句,正确,但如果 if 语句似乎为真(没有电子邮件为 ashfjks@sdhja.com),则不能与“if”语句一起使用,而是代码继续。这段代码的后半部分主要是对情况进行扩展。该行只能存在或不存在,所以我不明白为什么它不严格执行其中一个。我正在转换为站点安全的 PDO,这就是为什么不是所有的都在 PDO 中。如果这个问题过于本地化,我很抱歉?

$stmt = $pdo->prepare("SELECT * FROM table WHERE email = ?");
$stmt->execute(array("$email"));
$row3 = $stmt->fetch(PDO::FETCH_ASSOC);

while($row = $stmt->fetch()) {

  if ( ! $row3) {
    // Row3 doesn't exist -- this means no one in the database has this email, allow the person to join
    $query = "INSERT INTO table (username, email, password, join_date) VALUES ('$username', '$email', SHA('$password1'), NOW())";
    mysqli_query($dbc, $query); 
    $query = "SELECT * FROM table WHERE username = '$username'";
    $data2 = mysqli_query($dbc, $query);
  while ($row = mysqli_fetch_array($data2)) {

  $recipent = '' . $row['user_id'] . '';

    $query = "INSERT INTO messages (recipent, MsgTit, MsgR, MsgA, sender, time, readb, reada, MsgCon) VALUES ('$recipent', '$MsgTit', '$MsgR', '$MsgA', '$sender', NOW(), '$readb', '$reada', '$MsgCon')";
    mysqli_query($dbc, $query);

    // Aftermath.
    echo '<p>Your new account has been successfully created. You\'re now ready to <a href="game2.php" target="_blank">log in</a>. After this you should implement basic character-details on your users profile to begin the game.</p>';

    mysqli_close($dbc);
    exit();
  } }  
  else {
    // An account already exists for this email, so display an error message
    echo '<p class="error">An account already exists for this e-mail.</p>';
    $email = "";
  }
}
4

2 回答 2

2

+1 to answer from @Geoff_Montee, but here are a few more tips:

  • Make sure you check for errors after every prepare() or execute(). Report the error (but don't expose your SQL to the user), and fail gracefully.

  • Note that even though you checked for existence of a row matching $email, such a row could be created in the brief moment of time since your check and before you INSERT. This is a race condition. Even if you SELECT for a row matching $email, you should also use a UNIQUE constraint in the database, and catch errors when you execute the INSERT in case the UNIQUE constraint blocks the insert due to conflict.

  • SELECT email instead of SELECT *. If you have an index on email, then the query runs more efficiently because it can just check the index for the given value, instead of having to read all the columns of the table when you don't need them. This optimization is called an index-only query.

  • Likewise use SELECT user_id instead of SELECT *. Use SELECT * only when you really need to fetch all the columns.

  • Bcrypt is more secure than SHA for hashing passwords.

于 2012-10-31T21:57:03.083 回答
2

Your if statement will never be executed. You need to check the number of rows returned. This is what you want:

Note: I originally used $stmt->rowCount(), but the OP said that didn't work for him. But I'm pretty sure the cause of that error was coming from somewhere else.

if (!($stmt = $pdo->prepare("SELECT * FROM table WHERE email = ?"))) {
   //error
}

if (!$stmt->execute(array("$email"))) {
    //error
}
//The $row3 var you had was useless. Deleted that.

$count = 0;

while ($row = $stmt->fetch()) {
    $count++;
}

//The query returned 0 rows, so you know the email doesn't exist in the DB
if ($count== 0) {

    $query = "INSERT INTO table (username, email, password, join_date) VALUES ('$username', '$email', SHA('$password1'), NOW())";

    if (!mysqli_query($dbc, $query)) {
        //error
    }

    $query = "SELECT * FROM table WHERE username = '$username'";

    if (!($data2 = mysqli_query($dbc, $query))) {
        //error
    }

    while ($row = mysqli_fetch_array($data2)) {

        $recipent = '' . $row['user_id'] . '';

        $query = "INSERT INTO messages (recipent, MsgTit, MsgR, MsgA, sender, time, readb, reada, MsgCon) VALUES ('$recipent', '$MsgTit', '$MsgR', '$MsgA', '$sender', NOW(), '$readb', '$reada', '$MsgCon')";

        if (!mysqli_query($dbc, $query)) {
            //error
        }

       // Aftermath.
       echo '<p>Your new account has been successfully created. You\'re now ready to <a href="game2.php" target="_blank">log in</a>. After this you should implement basic character-details on your users profile to begin the game.</p>';

       mysqli_close($dbc);
       exit();
   }
}
//The query did not return 0 rows, so it does exist in the DB
else {
    // An account already exists for this email, so display an error message
    echo '<p class="error">An account already exists for this e-mail.</p>';
    $email = "";
}

And you should totally convert the rest of those queries to use PDO.

于 2012-10-31T21:57:42.677 回答