1

I am having a major problem with the PHP mail() function. I have a user sign-up page that generates an email for verification of their email address. Unfortunately and bizarrely, the function sends anywhere from 6 or 7 to 90+ emails to the same user. I do not understand how or why this is occurring, even after looking through others' posts on here.

Can someone help me debug this?

This is the code:

$first_name = mysql_real_escape_string($_POST['first_name']);
$last_name = mysql_real_escape_string($_POST['last_name']);
$email = mysql_real_escape_string($_POST['email']);
$username = strtoupper(mysql_real_escape_string($_POST['username']));
$password1 = mysql_real_escape_string($_POST['password1']);
$password2 = mysql_real_escape_string($_POST['password2']);
$termsofuse = mysql_real_escape_string($_POST['termsofuse']);
$status = mysql_real_escape_string($_POST['status']);
$approved = mysql_real_escape_string($_POST['approved']);
$acctype = mysql_real_escape_string($_POST['acctype']);
$industry = mysql_real_escape_string($_POST['industry']);
$newsletter = mysql_real_escape_string($_POST['newsletter']);
$contactname = mysql_real_escape_string($_POST['contactname']);
$contactnumber = mysql_real_escape_string($_POST['contactnumber']);

// Hashing of $password1
$password1 = sha256($password1);
$password2 = sha256($password2);

$hash = hash('sha256', $username);

// Check for existing username
$sql = "SELECT * FROM `members`";
$result2=mysql_query($sql);
while($row=mysql_fetch_array($result2)){
  $username2 = $row['username'];

  // If $username doesn't equal $username2 (meaning there isn't an existing username, and both passwords match, write to database
  if($username <> $username2 && $password1 === $password2){
    $sql = "INSERT INTO `members` (`id`, `first_name`, `last_name`, `email`, `username`, `password`, `termsofuse`, `status`, `approved`, `acctype`, `industry`, `newsletter`, `contactnumber`, `hash`, `since`) VALUES (NULL, '$first_name' , '$last_name' , '$email' , '$username' , '$password1' , '$termsofuse', 'Reg', '$approved', '$acctype', '$industry', '$newsletter', '$contactnumber', '$hash', NOW())";
    $result = mysql_query($sql) or die ("Can't insert".mysql_error());
    $to = $email; // Send email to user
    $subject = 'Signup Verification'; //Subject line in email
    $message = 'Welcome ' . $first_name . ','
    . "\r\n\r\n"
    . 'Thanks for signing up!'
    . "\r\n\r\n"
    . 'Your account has been created. To activate your account, click on the link below to get started!'
    . "\r\n\r\n"
    . 'http://www.radioman911.com/pages/CAD/verify.php?email=' . $email . '&hash=' . $hash . '';
    $headers = 'From: xxxx' . "\r\n" .
    'Reply-To: same xxxx as above' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();
    mail($to, $subject, $message, $headers, '-fxxxx same as above'); //Send the email
    header("location:new_member_sucess.php"); //yes, i know i spelled success wrong, but i also spelled it wrong in the page filename lol

  } else {
    echo "<style type='text/css'>A{text-decoration:none}</style>";
    echo "<body bgcolor='black'><font color='white' style='font-family:trebuchet ms;'>";
    echo "Passwords do not match or that username is already taken, please try again!<br>";
    echo "<a href='javascript: history.go(-1)'><font color='red'>Go back</a></font>";
  }
}
?>

Thanks!

3
  • I can't get What this is if($username <> $username2 Commented Jun 5, 2013 at 20:51
  • @phpNoOBఠ_ఠ // If $username doesn't equal $username2 (meaning there isn't an existing username, and both passwords match, write to database Commented Jun 5, 2013 at 20:52
  • 1
    Why not do the query SELECT * FROM 'members' WHERE members.username = username, and if it returns a result of zero matches, insert into database? One query, no looping, you'll save overhead and processing time. Commented Jun 5, 2013 at 20:58

5 Answers 5

1

Your problem lies with the SQL to check for duplicate usernames.

// Check for existing username
$sql = "SELECT * FROM `members`";
$result2=mysql_query($sql);
while($row=mysql_fetch_array($result2)){
    $username2 = $row['username'];

...

}}

I have taken your code, and made some minor changes. I have changed your SQL query to retrieve a count of users with the same username, instead of returning every username to check individually.

I have also taken the code around the mail() function out of a loop. If no duplicate usernames have been found, the $duplicateUsername variable is set to false, otherwise its set to true.

If $duplicateUsername is false, then the mail function is called... once, otherwise the error is displayed.

Please everything from // Check for existing username with the following:

// Check for existing username
$username = mysql_real_escape_string($username);
$duplicateUsername = false;


$sql = "SELECT COUNT(username) AS usernameCount FROM members WHERE username = '{$username}'";
$result2=mysql_query($sql);
while($row=mysql_fetch_array($result2)){
    $duplicateUsername = $row['usernameCount']>0 ? true : false;
}

if(!$duplicateUsername){
    $sql = "INSERT INTO `members` (`id`, `first_name`, `last_name`, `email`, `username`, `password`, `termsofuse`, `status`, `approved`, `acctype`, `industry`, `newsletter`, `contactnumber`, `hash`, `since`) VALUES (NULL, '$first_name' , '$last_name' , '$email' , '$username' , '$password1' , '$termsofuse', 'Reg', '$approved', '$acctype', '$industry', '$newsletter', '$contactnumber', '$hash', NOW())";

    $result = mysql_query($sql) or die ("Can't insert".mysql_error());

    $to = $email; // Send email to user
    $subject = 'Signup Verification'; //Subject line in email
    $message = 'Welcome ' . $first_name . ','
       . "\r\n\r\n"
       . 'Thanks for signing up!'
       . "\r\n\r\n"
       . 'Your account has been created. To activate your account, click on the link below to get started!'
       . "\r\n\r\n"
       . 'http://www.radioman911.com/pages/CAD/verify.php?email=' . $email . '&hash=' . $hash . '';
    $headers = 'From: xxxx' . "\r\n" .
         'Reply-To: same xxxx as above' . "\r\n" .
         'X-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers, '-fxxxx same as above');

    header("location:new_member_sucess.php");
} else {
    echo "<style type='text/css'>A{text-decoration:none}</style>";
    echo "<body bgcolor='black'><font color='white' style='font-family:trebuchet ms;'>";
    echo "Passwords do not match or that username is already taken, please try again!<br>";
    echo "<a href='javascript: history.go(-1)'><font color='red'>Go back</a></font>";
}
Sign up to request clarification or add additional context in comments.

8 Comments

Phil - Thanks very much! However, after implementing your changes, mysql_fetch_array() expects parameter 1 to be resource, boolean given .... In addition, it doesn't like the header being at the bottom anymore (which it didn't care before)
@Tim sorry, I made a mistake in the SQL! I forgot to enclose {$username} in quotes. I have updated the SQL statement so it should work now. It wouldn't like the header at the bottom because text has already been sent to the browser, but the SQL fix should resolve this issue as well :)
Oh okay. I have not seen the {$username} style before - is it older, newer, better, or...?
The curly quotes just tell the server that the code between them is a variable, you'll usually see this style between double quotes, like this: echo "Hello {$username}, Welcome back!"; Its called variable interpolation
Phil - it now says that the passwords don't match or the username is already taken. Neither of which is true. Any ideas?
|
1

Your while loop doesn't make any sense.
You actually loop over all users (all rows in your db) and every time the new user doesn't match the current row in your while loop you add the new user to the database and send the email each time.

This is what you should do:
Your query

$sql = "SELECT * FROM members";

is way to generic.
Use MySql for what it's good for and let the database find the match not your php script by iterating over the result set.
Use a query like this:

$sql = "SELECT count(*) as count FROM members WHERE username LIKE '$username'";
$result = mysql_query($sql);

and then check if the $result['count'] equals 0. If that's the case the new user doesn't exist yet and you can create the new user and send your email.

1 Comment

So delete the while loop and change the if($username <> $username2 && $password === $password2){ with if($result['count'] == 0 ....?
0

You are executing mail() in a while() loop that includes all of the users in your database.

Based the if statement in that condition, you are doing an insert and sending the email every time the user-supplied username doesn't match the current row and the password matches. Presumably, several of your users a lot of the same passwords.

You will need to update your query to include conditions to excludes non-matching users from the result set.

Comments

0

You're looping though all of your members if if the usernames don't match, but the passwords do, you add a user and send an e-mail. Usernames will almost never be identical and passwords might...

You should change your query to only query the database for that particular user, e.g.

$sql = "SELECT * FROMmembersWHERE username LIKE \"" . $username . \"";

Not an answer to your question, but you can shorten the first lines of your code to this:

foreach($_POST AS $k => $v){
  $$k = mysql_real_escape_string($v);
}
$username = strtoupper($username);

A lot shorter.

Comments

0

Your mail function is within while loop, so it's sending so many emails. please cut that code and place it above or below loop. Second, query is wrong, $sql = "SELECT * FROM members"; will select all members, use $sql = "SELECT * FROM members where ....."; i don't know column names. read, http://www.w3schools.com/php/php_mysql_where.asp

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.