Check if user exists with AJAX and PHP - javascript

I am trying to create a signup form that checks if the user exists in the database, I inserted a sample user and when I tried signing up with that user it didn't say its already been taken. What have I done wrong?
The JavaScript:
function formSubmit()
{
document.getElementById('email_valid').innerHTML = '';
var temail=document.forms["signup_form"]["temail"].value.replace(/^\s+|\s+$/g, '');
var atpos=temail.indexOf("#");
var dotpos=temail.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=temail.length)
{
//alert("Not a valid e-mail address");
setTimeout(function(){document.getElementById('email_valid').innerHTML = '<br/>Email must be valid...';},1000);
var temailsub=0;
}
else
{
$.post('/resources/forms/signup/email.php',{email: temail}, function(data){
document.getElementById('email_valid').innetHTML = data;
if(data.exists){
document.getElementById('email_valid').innetHTML = '<br/>The email address you entered is already in use.';
var temailsub=0;
}else{
var temailsub=1;
}
}, 'JSON');
}
if(temailsub==1e)
{
setTimeout(function(){document.getElementById("signup_form").submit();},1000);
}
else
{
return false;
}
}
The PHP file (email.php):
<?php
header('content-type: text/json');
require_once $_SERVER['DOCUMENT_ROOT']."/resources/settings.php";
$query = $pdo->prepare("SELECT * FROM users WHERE email=:email");
$query->execute(array(
":email"=> $_POST['email']
));
echo json_encode(array('exists' => $query->rowCount() > 0));
?>
I have checked and double checked the code, I still cannot see why its not detecting that the email has already been used... what do i need to do to fix this and avoid this in the future?

The problem is that PDOStatement::rowCount() returns the number of rows affected by the last SQL statement. You are performing a SELECT so this value will always be 0. SELECT does not affect any rows. Instead you need to count the number of rows:
$query = $pdo->prepare("SELECT COUNT(*) FROM users WHERE email=:email");
$query->execute(array(
":email"=> $_POST['email']
));
$rows = $query->fetchColumn();
echo json_encode(array('exists' => $rows);
Also from jtheman's comment above, you should replace innetHTML with innerHTML in your JavaScript.

Related

Encountering problem while posting and fetching data using php and ajax

My ajax code:
$('#name').keyup(function() {
var usercheck = $(this).val();
$('#nameAvailability').html('<img src="../SPR/assets/img/loading.gif" width="300" />'); //this part is working
$.post("../SPR/backend/username_availability_check.php", {user_name: usercheck} ,
function(data)
{
if (data.status == true)
{
$('#nameAvailability').parent('div').removeClass('has-error').addClass('has-success');
} else {
$('#nameAvailability').parent('div').removeClass('has-success').addClass('has-error');
}
$('#nameAvailability').html(data.msg); // not working
} ,'json');
});
My php code:
<?php
require("connection.php");
if(isset($_POST['user_name']) && $_POST['user_name'] != '')
{
$response = array();
$username = mysqli_real_escape_string($conn,$_POST['user_name']);
echo $username;
$sql = "select username from users where users.username='".$username."'";
$res = mysqli_query($conn, $sql);
$count = mysqli_num_rows($res);
if($count > 0)
{
$response['status'] = false;
$response['msg'] = 'Username already exists.';
}
else if(strlen($username) < 6 || strlen($username) > 15){
$response['status'] = false;
$response['msg'] = 'Username must be 6 to 15 characters';
}
else if (!preg_match("/^[a-zA-Z1-9]+$/", $username))
{
$response['status'] = false;
$response['msg'] = 'Use alphanumeric characters only.';
}
else
{
$response['status'] = true;
$response['msg'] = 'Username is available.';
}
echo json_encode($response);
echo $response;
}
?>
I have used session_start() in my index.php where user inputs his username in the input field with id 'name'
I have checked the given php code by running it individually by passing a custom username from the database and it works fine. So probably there's something wrong with the ajax code.
It is impossible to tell what your clientside code does based on what is posted here.
But in general, for debugging and to check if your serverside code works, do this:
Make a simple form, that POSTS to your PHP script.
<form action="whateveryourphpcodeisnamed.php" METHOD="POST">
<INPUT TYPE="TEXT" NAME="user_name">
<INPUT TYPE="SUBMIT" VALUE="TEST THE USERNAME">
</FORM>
And see what it says back to you.
Be sure to activate error_reporting during development.

jQuery AJAX check if email exists in database not working for some reason

I am trying to use jQuery, AJAX, PHP, and MySQL to check if an email entered into a form already exists in a database.
This is my current jQuery code :
$.post('check-email.php', {'suEmail' : $suEmail}, function(data) {
if(data=='exists') {
validForm = false;
$suRememberMeCheckbox.css('top', '70px');
$suRememberMeText.css('top', '68px');
$signUpSubmit.css('top', '102px');
$tosppText.css('top', '115px');
$suBox.css('height', '405px');
$suBox.css('top', '36%');
$errorText.text('The email has been taken.');
return false;
};
});
And this is my PHP code:
<?php include("dbconnect.php") ?>
<?php
$sql = "SELECT email FROM users WHERE email = '" .$_POST['suEmail'] . "'";
$select = mysqli_query($connection, $sql);
if (mysqli_num_rows($select) > 0) {
echo "exists";
}
?>
When I go through with the sign up form, when I use an email already in the database, the error text never changes to what I specified, but instead to some other error cases I have coded. Why is this not working! Thanks so much!
You may have extra whitespace in response
Try:
if(data.trim()=='exists') {

Preventing Multiple Unintended PHP Form Submissions

I run a website for a youth sports program that features schedules, standings, and score reporting using simple PHP scripts that manipulate data stored in a MySQL database.
After a game is played, the winning coach will access the score reporting form for that particular game, enter the information, and click submit to update the schedule and standings accordingly. They are then automatically redirected to the schedule page that they came from.
However, several times a season, a coach will unintentionally duplicate a score submission (sometimes creating as many as three or four instances) which does not affect the result posted on the schedule, but does throw the data in the standings out of whack. I'm not sure how exactly this is being accomplished, but I'm trying to fix the problem.
I've been reading up as much as possible on here and the web and believe that I need to implement some sort of token system to the reporting script, but I'm unsure how to exactly write the code? Any advice here would be GREATLY appreciated. Here is the script itself:
<?php
// Connect to the database:
require ('../mysqli_connect.php');
// Validate the school:
if (empty($_POST['school'])) {
echo "You forgot to enter your school.<br>";
$validate = 'false';
} elseif ($_POST['school'] != $_POST['away_team'] && $_POST['school'] != $_POST['home_team']) {
echo "Your school does not match one of the two on file for this game.<br>";
$validate = 'false';
} else {
$school = mysqli_real_escape_string($db, trim($_POST['school']));
$validate = 'true';
}
// Validate the password:
if (empty($_POST['pass'])) {
echo "You forgot to enter your password.<br>";
$validate = 'false';
} else {
$pass = mysqli_real_escape_string($db, trim($_POST['pass']));
$validate = 'true';
}
// Validate the away score:
if (!isset($_POST['away_score'])) {
echo "You forgot to enter the away score.<br>";
$validate = 'false';
} elseif (!is_numeric($_POST['away_score'])) {
echo "You entered an invalid score for the away team.<br>";
$validate = 'false';
} else {
$away_score_confirm = mysqli_real_escape_string($db, trim($_POST['away_score']));
$validate = 'true';
}
// Validate the home score:
if (!isset($_POST['away_score'])) {
echo "You forgot to enter the home score.<br>";
$validate = 'false';
} elseif (!is_numeric($_POST['$home_score']) && $_POST['$home_score'] < 0 ) {
echo "You entered an invalid score for the home team.<br>";
$validate = 'false';
} else {
$home_score_confirm = mysqli_real_escape_string($db, trim($_POST['home_score']));
$validate = 'true';
}
// Determine the winner and loser, and set variables:
if ($_POST['away_score'] > $_POST['home_score']) {
$winner = mysqli_real_escape_string($db, trim($_POST['away_team']));
$winner_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
$loser = mysqli_real_escape_string($db, trim($_POST['home_team']));
$loser_score = mysqli_real_escape_string($db, trim($_POST['home_score']));
$tie = 'no';
} else if ($_POST['away_score'] < $_POST['home_score']) {
$winner = mysqli_real_escape_string($db, trim($_POST['home_team']));
$winner_score = mysqli_real_escape_string($db, trim($_POST['home_score']));
$loser = mysqli_real_escape_string($db, trim($_POST['away_team']));
$loser_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
$tie = 'no';
} else if ($_POST['away_score'] == $_POST['home_score']) {
$tie = 'yes';
$tie1 = mysqli_real_escape_string($db, trim($_POST['away_team']));
$tie2 = mysqli_real_escape_string($db, trim($_POST['home_team']));
$tie_score = mysqli_real_escape_string($db, trim($_POST['away_score']));
}
// Declare remaining hidden inputs as variables:
$league = $_POST['league'];
$table = mysqli_real_escape_string($db, $_POST['table']);
$game_id = mysqli_real_escape_string($db, $_POST['game_id']);
$sport = $_POST['sport'];
// Declare remaining hidden inputs as variables:
$standings_league = $table . "_standings";
// If all conditions are met, process the form:
if ($validate != 'false') {
$q1 = "SELECT school_id FROM user_schools WHERE (school_name='$school' AND pass='$pass')";
$r1 = mysqli_query($db, $q1);
$num = mysqli_num_rows($r1);
if ($num == 1) {
// Get the game ID:
$q2 = "SELECT $game_id FROM $table";
$r2 = mysqli_query($db, $q2);
// Get the row for the game ID:
$row = mysqli_fetch_array($r2, MYSQLI_NUM);
// Perform an UPDATE query to modify the game scores:
$q3 = "UPDATE $table SET home_score='$home_score_confirm', away_score='$away_score_confirm' WHERE game_id=$row[0]";
$r3 = mysqli_query($db, $q3);
if (mysqli_affected_rows($db) == 1) {
$confirm = 'true';
} else {
$confirm = 'false';
}
// Update the winning team in the standings:
$q4 = "SELECT school_id FROM $standings_league WHERE school_name='$winner'";
$r4 = mysqli_query($db, $q4);
// Get the row for the school:
$row2 = mysqli_fetch_array($r4, MYSQLI_NUM);
$q5 = "UPDATE $standings_league SET games=games + 1, win=win + 1, pts_for=pts_for + '$winner_score', pts_against=pts_against + '$loser_score' WHERE school_id=$row2[0]";
$r5 = mysqli_query($db, $q5);
$q6 = "UPDATE $standings_league SET pct=(win / games), avg_for=(pts_for / games), avg_against=(pts_against / games) WHERE school_id=$row2[0]";
$r6 = mysqli_query($db, $q6);
// Update the losing team in the standings:
$q7 = "SELECT school_id FROM $standings_league WHERE school_name='$loser'";
$r7 = mysqli_query($db, $q7);
// Get the row for the school:
$row3 = mysqli_fetch_array($r7, MYSQLI_NUM);
$q8 = "UPDATE $standings_league SET games=games + 1, loss=loss+1, pts_for=pts_for + '$loser_score', pts_against=pts_against + '$winner_score' WHERE school_id=$row3[0]";
$r8 = mysqli_query($db, $q8);
$q9 = "UPDATE $standings_league SET pct=(win / games), avg_for=(pts_for / games), avg_against=(pts_against / games) WHERE school_id=$row3[0]";
$r9 = mysqli_query($db, $q9);
if ($confirm != 'false') {
header('Location: schedules_' . $sport . '_' . $league . '.html?league=' . $league .'&table=' . $table);
} else {
echo "The scores could not be reported due to a system error. Apologies for the inconvenience. If this problem continues, please contact us directly.";
}
} else {
echo "Your school and password combination do not match those on file for this game.";
}
}
mysqli_close($db);
?>
My guess is that these coaches are simply clicking the submit button multiple times while the form is waiting for a response from the server. You could use JS to disable (or hide) the button after the first click:
var button = document.querySelector('input[type=submit]'); // Use whatever selector is appropriate here
button.addEventListener('click', function(ev) {
if (!button.classList.contains('submitting')) { // If this is our first click...
button.className += ' submitting';
} else { // Otherwise prevent submission
ev.preventDefault();
}
});
If you have jQuery available to you, you could also just handle the entire submission process via JS and block it there.
You should be aware of presenting some sort of feedback onto the screen to let the user know that a submission is currently in progress, that'll help alleviate some button mashing as well.
One solution is to add a unique value to the form and when its submitted, add the value to a session. If they hit submit button more than once ( probably what is happening ), it will accept only one submition
Example:
<form>
<input type="hidden" name="submit_id" value="<?php echo mt_rand(); ?>">
// rest of the form
</form>
Php file recieving:
<?php
session_start();
if ( isset( $_POST['submit_id'] ) ) {
if ( !isset( $_SESSION['submit_id'] ) ) {
$_SESSION['submit_id'] = array();
}
if ( !in_array( $_POST['submit_id'], $_SESSION['submit_id'] ) ) {
// validate posted values
// when data is valid, register form as submitted
$_SESSION['submit_id'][] = $_POST['submit_id'];
// add the submitted form data to database
}
else {
echo 'Your data has already been submitted';
}
}
I don't want to read your code so I'll suggest a strategy.
I agree with #relic. Your coach is probably double-clicking the button.
If you can assume that different users will never submit two forms in the same second, then you can "filter" your table to accept only one entry for any given second. Make an index for the (new) seconds column, and make it unique. This will prevent insertions of rows to that table if an entry already exits for that second.
If this leads to conflicts, you can introduce restrictions that enforce every entry to be unique for a combination of other fields in the table. This is called compound keys (SQL). You formulate something like, for this game and user, there can only be one score registration.
MySQL:
create table scores (game_id int, user_id int, score int );
alter table scores add unique index uniq_gus (game_id, user_id, score);
insert into scores (game_id, user_id, score) values (1, 1, 10);
insert into scores (game_id, user_id, score) values (1, 1, 10);
ERROR 1062 (23000): Duplicate entry '1-1-10' for key 'uniq_gus'
In addition, you may want to prevent double-submissions (assuming jQuery):
(function($){
var btn = $('button[type="submit"]');
btn.click(function(event){
event.preventDefault();
btn.attr('disabled','disabled');
$.ajax({
url: 'http://foo.bar/form-endpoint.php',
success: function (data, status, xhr) {
btn.removeAttr('disabled');
},
})
})
})(jQuery);

ajax login form doesn't work

I am trying to pass user's info from mysql to the webpage, if the user has logged in but can't get it to work. If I put a wrong email or password it will show the error message but if the credentials are ok it would do anything...
on php file:
$sql = "SELECT * FROM users WHERE email='$l_email' AND password='$l_password'";
$query = mysql_query($sql) or die ('Error: ' . mysql_error());
$num_rows = mysql_num_rows($query);
if($num_rows < 1)
{
echo "You have entered a wrong email or password!";
}
else {
$memberInfo = array();
while( $row = mysql_fetch_array( $query ) )
{
$memberInfo[] = $row;
}
return $memberInfo;
echo json_encode( $memberInfo );
//echo "1";
}
on js file:
$.post("./includes/checkOut.php",{ l_email1: l_email, l_password1: l_password },
function(data) {
if(data=='1')
$("#checkOut_form")[0].reset();
$("#login_returnmessage").html("");
$("#memberInfo").hide("");
var memberInfo = jQuery.parseJSON(memberInfo);
for( var i in memberInfo )
{
var f_name = memberInfo[i].f_name;
var l_name = memberInfo[i].l_name;
var phone = memberInfo[i].phone;
}
$("#loggedinInfo").show("");
$('#_f_name').val(f_name);
$('#_l_name').val(l_name);
$('#_email').val(l_email);
$('#_phone').val(phone);
}
$("#login_returnmessage").html(data);
});
If you use return outside a function then it terminates the script at that point. This is exactly what you're doing here:
return $memberInfo;
echo json_encode( $memberInfo );
//echo "1";
You need to remove the return statement.
You should also add a Content-type: header to the response to tell the browser to expect JSON:
header('Content-type:application/json');
echo json_encode( $memberInfo );
Your Javascript code is checking the response for the value 1, which you're not sending, so the code that updates the display won't execute.
Lastly:
don't store passwords unencrypted - use password_hash()
don't use mysql as it's deprecated - use mysqli or PDO
ensure you escape your inputs before passing them to the database (or better, use prepared statements (not supported by mysql_*()).

PHP AJAX always returning the same result

So I'm trying to check if the email is already in use (for a password reset). So I have my JS
//Check if email exists
$(document).ready(function() {
//listens for typing on the desired field
$("#email").keyup(function() {
//gets the value of the field
var email = $("#email").val();
//here is where you send the desired data to the PHP file using ajax
$.post("../classes/check.php", {email:email},
function(result) {
if(result == 1) {
//Email available
console.log("Good");
}
else {
//the email is not available
console.log("Bad");
}
});
});
});
And then my PHP
<?php
//Include DB
include_once '../db.php';
if(isset($_POST['email'])){
//Get data
$email = htmlspecialchars($_POST['email'], ENT_QUOTES, 'UTF-8');
}
else{
header('Location: /');
}
//Send requst to DB
$stmt = $con->prepare("SELECT * FROM users WHERE email = :email");
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
$stmt->execute();
if($stmt->rowCount() > 0){
//Email found
echo 1;
}
else{
//Email not found
echo 0;
}
So I start off by making sure there's a recording in my DB. Which there is, so I enter it. Now I go over to the console and all I get is Bad, which means that the email is not found, but it's in the database. So I'd assume all it returns is 0. Any ideas? Could it be an error in my code?
The PDO documentation warns that rowCount might not work with all drivers. A more reliable and efficient way to do it is:
$stmt = $con->prepare("SELECT COUNT(*) as count FROM users WHERE email = :email");
$stmt->bindValue(':email', $email, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row['count'] > 0) {
echo 1;
} else {
echo 0;
}
Another thing to try:
$email = trim($_POST['email']);
because sometimes there's extra whitespace in theinput field.

Categories

Resources