A forgot-password page should return the same public response whether an account exists or not. If the account exists, create a short-lived random token and email a reset link. Do not email the existing password or reveal account existence.
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
// Public response stays the same to reduce account enumeration.
$message = 'If the account exists, a password-reset link will be sent.';
if ($email) {
$stmt = $pdo->prepare('SELECT id FROM members WHERE email = :email');
$stmt->execute([':email' => $email]);
$memberId = $stmt->fetchColumn();
if ($memberId) {
$token = random_bytes(32);
$tokenHash = hash('sha256', $token);
$expiresAt = (new DateTimeImmutable('+30 minutes'))->format('Y-m-d H:i:s');
// Store $tokenHash and $expiresAt, then email the raw token in a reset URL.
}
}
echo htmlspecialchars($message, ENT_QUOTES, 'UTF-8');
?>
The form should never email an existing password or reveal whether the submitted address is registered. Validate the email, return the same public message for every request, and—when the account exists—create a short-lived reset token as shown in the recommended workflow above.
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$message = 'If the account exists, a password-reset link will be sent.';
if ($email) {
$stmt = $pdo->prepare('SELECT id FROM members WHERE email = :email');
$stmt->execute([':email' => $email]);
$memberId = $stmt->fetchColumn();
if ($memberId) {
$token = bin2hex(random_bytes(32));
// Store a hash of the token with an expiry, then email a reset link.
}
}
echo htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
?>
password_hash(), so the original value is not recoverable. Send a one-time reset link instead.Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.
| Sipence | 26-07-2012 |
| yah!! this article is really helpful for me. | |
| macky | 10-08-2012 |
| Hi ahm is this script running 100%? coz ahm i will be using this script | |
| Nathan | 15-08-2012 |
| I used the script above (I am not encrypting at this time). However, when I place my email address in my forgot password form, I receive the message "Your email address is not correct". I checked the database and my email address is there. Help! | |
| smo | 16-08-2012 |
| The checking of email address is done by ensuring presence of @ and . in you email address. So it should work. Just try to print once above the checking conditions. | |
| luisa | 28-08-2012 |
| is this really working... i need this tutorial for our website thank you. | |
| jaharlal | 03-04-2013 |
| Yes!! Really a fantastic script without any fees. Tank You | |
| Martin Britton | 29-04-2013 |
| My database has multiple tables in it. How do I get the script to access the right table? It keeps returning saying email address is not correct even though it is. | |
| mannyloz | 30-09-2013 |
| I have tried and tried to make this script work in our website however, it keeps displaying "There is some system problem in sending login details to your address. Please contact site-admin." Please HELP! | |
| smo | 04-10-2013 |
| Contact your host asking about sending mail. Or Just check if mail function is working in your site or not. | |
| Ramya | 27-11-2013 |
| Every thing works fine except forgot password. Is there any alternative way to give site_url ??? | |
| rahiman | 23-08-2014 |
| its good | |
| FalconCoder | 11-09-2014 |
| if my passwords in database hash(encrypted) what i should i do? | |
| senthil | 28-10-2014 |
| hi gud concept | |
| Owen | 09-12-2014 |
| Then what is the answer | |
| Sherry | 07-09-2015 |
| its 100% working Friends...!!! | |