Ok, here we go.... I'm assuming a few things though:
1) You have your login/registration pages already sorted
2) The password is stored in the database using an MD5 hash
3) You know how to connect to your database and stuff as I will miss this code out
What you have is a form on a page that allows somebody to enter an email address. This email is checked against the database, and if a matching address is found an email will be sent to that address with the new password. The new password will also need storing in the database as an MD5 hash in place of the old one.
Step one: creating the form for entering an email
This form is nothing special. It loads itself (forgot_password.php) when it is submitted. It has a text input for the email address, a submit, and a hidden field so we can tell if this form has been submitted.
It is also sticky, meaning that if the user enters an incorrect email it will be automatically re-entered into the field so it can be corrected.
HTML Code:
<h1>Reset your password</h1>
<p>Enter your email address below and your password will be reset.</p>
<form action="forgot_password.php" method="post">
<table width="100%" cellpadding="3px" border="0">
<tr>
<td>Email address:</td>
<td><input type="text" name="email" size="20" maxlength="80" value="<?php if (isset($_POST['email'])) echo $_POST['email']; ?>" /></td>
</tr><tr>
<td> </td>
<td><input type="submit" name="submit" value="Reset my password" /></td>
</tr>
</table>
<input type="hidden" name="submitted" value="TRUE" />
</form>
Step two: handle the form if it has been submitted
This PHP code will deal with the password reset if the form has been submitted. The code here is pretty complex but handles all the validation needed as well, so it should run fine if you can pick your way through it.
NOTE: This code is to be entered into the same file as the HTML code above, and must appear before the HTML code.
PHP Code:
// Handle form if it has been submitted
if (isset($_POST['submitted'])) {
require_once(MYSQL); // This is how I connect to the db
// Assume no matching email in db
$uid = FALSE;
// Validate the email address to ensure one is entered
if (!empty($_POST['email'])) {
// Check to see if email exists in database
$q = 'SELECT user_id FROM users WHERE email="' . mysqli_real_escape_string($dbc, $_POST['email']) . '"';
$r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
if (mysqli_num_rows($r) == 1) { // Retrieve the user id
list($uid) = mysqli_fetch_array($r, MYSQLI_NUM);
} else { // No email found so display error
echo '<p class="error">The submitted email address does not match our records.</p>';
}
} else { // No email submitted
echo '<p class="error">You didn\'t enter an email address.</p>';
} // End of check if email in database
if ($uid) { // If email exists and UID has been set
// Create a new random password
$p = substr(md5(uniqid(rand(), true)), 3, 10);
// Update the database with the new password
$q = "UPDATE users SET pass=MD5('$p') WHERE user_id=$uid LIMIT 1";
$r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
if (mysqli_affected_rows($dbc)) { // If database was updated
// Send the email to the user
$body = "Your password has been changed to '$p'.";
mail($_POST['email'], 'Password reset', $body, 'From: no-reply@address.com');
// Print a message on screen
echo '<h3>Your password has been changed. You will receive the new password at the registered email address.</h3>';
mysqli_close($dbc);
exit(); // Quit this script so form is not shown again
} else { // If an error occurred somewhere
echo '<p class="error">Your password could not be changed due to a system error.</p>';
}
} else { // Email address failed validation
echo '<p class="error">Please try again.</p>';
}
mysqli_close($dbc);
} // End of SUBMITTED IF statement
This might look a little complex, but if you read the helpers for each item I'm sure you'll understand. Before I finish posting I'll just draw attention to the code that creates, emails and stores the new password:
This creates a new password from a random number that has been MD5'ed and cut to 10 characters in size starting from the 3rd character - just a way to create a really random new password. This is stored in $p and might generate something like:
cb962ac590 - Remember that this is the password.
PHP Code:
// Create a new random password
$p = substr(md5(uniqid(rand(), true)), 3, 10);
Now we need to add the new password to the database, in place of the old one. We need to convert the new password to an MD5 hash for storage in the database (the MD5 in the last code was just to create something random). This MD5 hash will be something completely obscure.
PHP Code:
// Update the database with the new password
$q = "UPDATE users SET pass=MD5('$p') WHERE user_id=$uid LIMIT 1";
$r = mysqli_query($dbc, $q) or trigger_error("Query: $q\n<br />MySQL Error: " . mysqli_error($dbc));
If the new password was successfully saved to the database then we need to email the user to alert them that the password is now changed. We will send the password in plain text so it will read something like:
"Your password has been changed to cb962ac590."
PHP Code:
// Send the email to the user
$body = "Your password has been changed to '$p'.";
mail($_POST['email'], 'Password reset', $body, 'From: no-reply@address.com');
I've really tried to make this clear for you, but if you need more help post back and I will try my hardest to trim it down.