Xtremer360 Posted June 23, 2011 Share Posted June 23, 2011 What I'm trying to do is figure out how I can get the answers from the database to check against the answers from the user posted answers to see if they are equal and what I have now does not work. <?php session_start(); // Include the database page require ('../inc/dbconfig.php'); require ('../inc/global_functions.php'); //Login submitted if (isset($_POST['submit'])) { // Errors defined as not being any $errors = "no"; if((empty($_POST['answer1'])) || (trim($_POST['answer1'])=="") || ($_POST['answer1'] == NULL) || (!isset($_POST['answer1']))){$errors = "yes";} if((empty($_POST['answer2'])) || (trim($_POST['answer2'])=="") || ($_POST['answer2'] == NULL) || (!isset($_POST['answer2']))){$errors = "yes";} // Error checking, make sure all form fields have input if ($errors == "yes") { // Not all fields were entered error $message = "You must enter values to all of the form fields!"; $output = array('errorsExist' => true, 'message' => $message); } else { $userID = mysqli_real_escape_string($dbc,$_POST['userID']); $answer1Post = mysqli_real_escape_string($dbc,$_POST['answer1']); $answer2Post = mysqli_real_escape_string($dbc,$_POST['answer2']); $question1 = mysqli_real_escape_string($dbc,$_POST['question1']); $question2 = mysqli_real_escape_string($dbc,$_POST['question2']); $query = "SELECT * FROM manager_users_secretAnswers WHERE userID = '".$userID."'"; $result = mysqli_query($dbc,$query); // Count number of returned results from query if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_array($result)) { $answer = $row['answer']; // Comparing the database password with the posted password if (($answer == $answer1Post) && ($answer == $answer2Post)) { } else { $errors = "yes"; $message = "Your answers did not match the answers inside the database!"; $output = array('errorsExist' => true, 'message' => $message); } } } else { $errors = "yes"; $message = "We did not find any answers for your questions! Please consult the site administrator!"; $output = array('errorsExist' => true, 'message' => $message); } } } //Output the result $output = json_encode($output); echo $output; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 23, 2011 Share Posted June 23, 2011 First of all do not use "no" and "yes" for the $errors value. use the Boolean values of true/false (i.e. not the string values). It makes your code more logical. Then you don't need to do a test such as if($errors=='yes') Instead you can just do if($errors) Second, you have unnecessary duplication in your validation of the POSTed fields. You first check if the field is empty then check if the trimmed field is ="". You can do one check for that using if( empty(trim($_POST['fieldname'])) ) Also, I'm not sure it is even possible to have a POST value sent as NULL, so that validation is unnecessary. Now, looking at the logic of the code I am assuming that there are multiple records in the table for each user. Any appear to be trying to validate the user input to the records in the database looking for a match. But, you are trying to check a single value in the DB to see if it is equal to both answer1 and answer2 from the user input. That doesn't make sense to me. Are you asking the user to input the same value twice? If so, you could do that validation before running the query. Or, are there really TWO values in the DB record that you want to be validating the POSTed values against? if (($answer == $answer1Post) && ($answer == $answer2Post)) { I also see that you are running mysql_real_escape_string() on all the values, but you aren't using them in the query - that makes no sense. Also, you have an empty IF condition. Just reverse your logic and remove the ELSE condition. Plus, there is a problem with your logic. If there are multiple records to be checked and the user input matches one of the records the loop will continue to the next record, which may not match. So the result will be that there are no matches. You need to exit the loop when a match is encountered. Since you are comparing strings and they have to exactly match, you should convert the value to all lower or upper case (assuming these aren't passwords). You can resolve ALL these issues by changing your query to just look for a matching record instead of getting all of them and looping through them. But, then you would only have one error message that there were no matching records rather than the other message for no answers int he DB. Lastly, if you are not getting the results you expect add some debugging code to output values so you can see what is happening. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 23, 2011 Author Share Posted June 23, 2011 Second, you have unnecessary duplication in your validation of the POSTed fields. You first check if the field is empty then check if the trimmed field is ="". You can do one check for that using if( empty(trim($_POST['fieldname'])) ) Also, I'm not sure it is even possible to have a POST value sent as NULL, so that validation is unnecessary. What about to see if its not set? Do I need that? Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 23, 2011 Author Share Posted June 23, 2011 I did turn it into this: if (empty(trim($_POST['answer1']))) {$errors = true;} but then now I get a "Can't use function return value" and not sure why. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 23, 2011 Author Share Posted June 23, 2011 Any ideas why I'm getting that error? Quote Link to comment Share on other sites More sharing options...
wildteen88 Posted June 23, 2011 Share Posted June 23, 2011 You cannot use trim that way. You have to compare the return value of trim() to an empty string to check whether $_POST['answer1'] is emtpy. if(trim($_POST['answer1']) == '') { $errors = true; } Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 23, 2011 Author Share Posted June 23, 2011 Now, looking at the logic of the code I am assuming that there are multiple records in the table for each user. Any appear to be trying to validate the user input to the records in the database looking for a match. But, you are trying to check a single value in the DB to see if it is equal to both answer1 and answer2 from the user input. That doesn't make sense to me. Are you asking the user to input the same value twice? If so, you could do that validation before running the query. Or, are there really TWO values in the DB record that you want to be validating the POSTed values against? if (($answer == $answer1Post) && ($answer == $answer2Post)) { Okay so I'm looping through the results that contains two questionIDs and two answers and I'm trying to match the two answers with the two answers from the form submission. Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 23, 2011 Share Posted June 23, 2011 Now, looking at the logic of the code I am assuming that there are multiple records in the table for each user. Any appear to be trying to validate the user input to the records in the database looking for a match. But, you are trying to check a single value in the DB to see if it is equal to both answer1 and answer2 from the user input. That doesn't make sense to me. Are you asking the user to input the same value twice? If so, you could do that validation before running the query. Or, are there really TWO values in the DB record that you want to be validating the POSTed values against? if (($answer == $answer1Post) && ($answer == $answer2Post)) { Okay so I'm looping through the results that contains two questionIDs and two answers and I'm trying to match the two answers with the two answers from the form submission. What you just stated doesn't seem to match your code. You are comparing ONE value from the database, $answer, against TWO values submitted by the user: $answer1Post & $answer2Post Also, can there be multiple records returned from the query? If so, your code will fail at least half the time. Your IF condition would constitute a match, but all you have is an empty code block. So, if you find a match you do nothing. Then you check the next record. So, if the LAST record returned from the query fails you will get a failure even if there were previous records that matched. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 23, 2011 Author Share Posted June 23, 2011 I know what I have for that is incorrect I"m just not sure how to correct so that the desired task gets coded correctly. Basically I have the table secretAnswers with fields id, userID, questionID, answer. For each user there will be two rows returned such as : 1, 10001, 2, Arizona; 2, 10001, 3, 1982. Lets say that the user posted data was answer1 Arizona answer2 1982 question1 2 question2 3 submit Enter userID 10001 Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 any continuing ideas on this? Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 Here's my new updated code which somewhat works however its still not matching the correct values together. So I do need to factor in somehow is a where clause for each question with the question id. <?php // Include the database page require ('../inc/dbconfig.php'); require ('../inc/global_functions.php'); //Login submitted if (isset($_POST['submit'])) { // Errors defined as not being any $errors = false; if (trim($_POST['answer1']) == '') { $errors = true; } if (trim($_POST['answer2']) == '') { $errors = true; } // Error checking, make sure all form fields have input if ($errors) { // Not all fields were entered error $message = "You must enter values to all of the form fields!"; $output = array('errorsExist' => $errors, 'message' => $message); } else { $userID = mysqli_real_escape_string($dbc,$_POST['userID']); $answer1Post = mysqli_real_escape_string($dbc,$_POST['answer1']); $answer2Post = mysqli_real_escape_string($dbc,$_POST['answer2']); $question1 = mysqli_real_escape_string($dbc,$_POST['question1']); $question2 = mysqli_real_escape_string($dbc,$_POST['question2']); if ($statusID == 1) { // User was not verified error $errors = true; $message = "Sorry you must verify your email address before logging in. Didn't get the verification email? Don't worry we can <a href=\"javascript:void(0);\" id=\"resendVerification\">resend it</a>!"; $output = array('errorsExist' => $errors, 'message' => $message); } else if ($statusID == 3) { // User is suspended error $errors = true; $message = "Your account has been suspended. If you would like to contest this action <a href=\"javascript:void(0);\" id=\"contestSuspension\">click here</a>!"; $output = array('errorsExist' => $errors, 'message' => $message); } else if ($statusID == 4) { // User is pending deletion error $errors = true; $message = "Your account is currently deleted, would you like to reactivate it? <a href=\"javascript:void(0);\" id=\"undeleteAccount\">Yes, Reactivate</a>!"; $output = array('errorsExist' => $errors, 'message' => $message); } else { $query = "SELECT * FROM manager_users_hacking WHERE userID = '".$userID."'"; $result = mysqli_query($dbc,$query); $row = mysqli_fetch_array($result); $lockDate = $row['lockDate']; // Find out if user is locked out of their account if ($lockDate !== "0000-00-00 00:00:00") { // Account locked error $errors = true; $message = "Your account is currently locked, we appologize for the inconvienence!"; $output = array('errorsExist' => $errors, 'message' => $message); } else { $query = "SELECT * FROM manager_users_secretAnswers WHERE userID = '".$userID."'"; $result = mysqli_query($dbc,$query); // Count number of returned results from query if (mysqli_num_rows($result) > 0) { while ($row = mysqli_fetch_array($result)) { $answer = $row['answer']; // Comparing the database password with the posted password if ($answer == $answer1Post) { // The first answer is correct $errors = false; } else if ($answer == $answer2Post) { // The second answer is correct $errors = false; } else { $errors = true; } } if ($errors == true) { // Retrieve IP Address of user trying to hack into account $hackerIPAddress = $_SERVER['REMOTE_ADDR']; // Insert hacker info into database for storage and run query $query2 = "INSERT INTO manager_users_hacking (hackerIPAddress, userID, lockDate) VALUES ('".$hackerIPAddress."','".$userID."', CURRENT_TIMESTAMP)"; $result2 = mysqli_query($dbc,$query2); $errors = true; $message = "Your answers did not match the answers inside the database!"; $output = array('errorsExist' => $errors, 'message' => $message); } else { $errors = false; $message = "Your answers were correct you will be redirected to the password change form!"; $output = array('errorsExist' => $errors, 'message' => $message); } } else { $errors = true; $message = "We did not find any answers for your questions! Please consult the site administrator!"; $output = array('errorsExist' => $true, 'message' => $message); } } } } } //Output the result $output = json_encode($output); echo $output; ?> Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 24, 2011 Share Posted June 24, 2011 I previously explained the error in your original logic. Not sure where you came up with that last code. If you are looking for one record that matches then you need to STOP the loop as soon as you have found a match (or alternatively set the code up to assume a false match and only set to true if a match is found). The problem with your logic is that even if you find a match you continue processing more records from the query. So, you would only have the results of the LAST record. Example $searchValue = "foo"; //Set a variable to detemine if a match was found - assume false $matchFound = false; //Loop through the Db results to look for a match while($row = mysql_fetch_assoc($result)) { if($searchValue = $row['fieldName']) { //A match was found - set flag to true $matchFound = true; //Exit the loop no need to check more records break; } } Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 I don't think you understand this is for a users secret questions for verifying that they are the user that requested the forgot password form okay so after the user fills out the username or email from the forgot password form it takes them to secret questions were it gets the username or email and queries the database for the questions that the user wanted at registration and then when they get to the secret questions form it shows both questions plus text boxes to input the answers to be able to check against the database one more time to verify that the account isn't getting hacked into and if BOTH answers are correct for their specific questions which the ids are passed along in the POST variables as well then the user will be emailed a temp password and if either of the answers are wrong then the account will be locked and the user will be sent back to the index page. Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 24, 2011 Share Posted June 24, 2011 To be honest, I really don't care about what this is all used for. You do not seem to understand that your logic is flawed. I would have been able to provide a much more specific solution for you but you never answered several of the questions I posed previously. Specifically, are there multiple records for each user. Although you never answered that, I assume by your last explanation and your original code that you have a separate record for each question/answer pair? But, what really doesn't make sense is that you are only comparing to see fi the user submitted answers match one of the answers for the user. You are not verifying that the answer is the correct answer for any specific question. If that is what you are doing, then you should be passing an identifier with the POST data to explicitly determine which question each answer belongs to. I would love to help you further, but it would take a complete rewrite of your code and your requirements are still vague. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 There are ALWAYS two answers for each user so yes there are multiple rows for each user. As far as knowing which answer goes with which question should be obvious because I have answer1Post and question1 and answer2Post and question2. I know my coding is flawed as I'm struggling to find the correct way to write the logic. I do appreciate you responding though. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 I hope that helps. Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 24, 2011 Share Posted June 24, 2011 As far as knowing which answer goes with which question should be obvious because I have answer1Post and question1 and answer2Post and question2. Ok, but in your code you don't do any validation that the answer matches the question - only that the answer matches one of the possible answers. Plus, it it not obvious what question1 and question2 contain. Are these the "text" values of the questions? If so, you should not be doing that. You should be passing in the POST data the IDs of the manager_users_secretAnswers records and the answers provided by the user. In fact you could do both within the inputs for the answers. Something like this: Answer 1: <input type="text" name="answer[3]" /> Answer 2: <input type="text" name="answer[8]" /> The 3 and the 8 represent the IDs for the associated questions that the user is supposed to enter (I would assume you would echo the question text next to those fields). Then the implementation of checking the input is fairly easy. Just do ONE query with specific criteria for both questionID/answer values and check that the number of records returned = 2. $userID = mysqli_real_escape_string($dbc, $_POST['userID']); $whereParts = array(); foreach($_POST['answer'] as $id => $answer) { $id = intval($id); $answer = mysqli_real_escape_string($dbc, $answer); $whereParts[] = "id='$id' AND answer = '$answer'" } $query = "SELECT * FROM manager_users_secretAnswers WHERE userID = '{$userID}' AND ( ({$whereParts[0]}) OR ({$whereParts[1]}) )"; $result = mysqli_query($dbc, $query); if(mysql_num_rows($result)!==2) { //Both answer did not match } else { //Both answers matched } Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 That all makes amazing since thank you for your time and effort. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 is there a way to identify which one is answer1 and answer2 so that I can just find answer1 and get its questionID with the userID and then select the answer and then check that against what the posted answer was from the form. Just so I can differentiate so that they can't try and trick the database. Quote Link to comment Share on other sites More sharing options...
Xtremer360 Posted June 24, 2011 Author Share Posted June 24, 2011 What should happen is you must fill out both answers. What I want to happen is have it take what the user typed for the first question and then select the answer for that user that matches the questionID of that question against the posted answer from the form and see if they match and if they do then take the second questions answer to the db and then select the answer for that user that matches the questionID of that question against the posted answer from the form and see if they match and if they do then its a success and the user will go redirected to the new password form. Quote Link to comment Share on other sites More sharing options...
Psycho Posted June 25, 2011 Share Posted June 25, 2011 I don't think you understand the logic I provided. Using that solution it ensures that answer 1 matches question 1 and answer 2 matches question 2. You could do one query to validate answer 1 then do another query to validate answer 2. But that is inefficient. Just do one query to validate that both answers match the appropriate questions. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.