Make PHP Sites

Last updated: 2015-02-28

Changing passwords

In this section, we'll go over how to provide a way for users to change their account password. We recommend checking out our lesson about a user login if you aren't sure how to start.

The code for this version will be written in a procedural method.

Requirements

Refer to the Get Started section to know what you need to use this tutorial. You must also have an understanding of HTML and how a web page is constructed.

We'll go through this assuming you know how to make an HTML form, use a MySQL database and understand the users's $_SESSION variables that we used in our lesson about a user login.

Prerequisites

To use this tutorial, we recommend that you use our other lesson, our User log-in and log-out.

Contents

The MySQL database

To allow a user to modify their password, we'll need the database holding their information. We will be using a MySQL database created in previous lessons, including our lesson about a user login. Feel free to use any kind with which you are familiar as long as you can adapt our code to fit correctly.

We'll use the database created in our other lesson about user registration. This is the table we will be using to log in a user.

Table: users

Column Type Description
userID INT (11) This will be the primary key. It is a unique ID number assigned to each individual user. It should be set to increment automatically.
email Varchar (250) This will hold the user's email address. They'll use this to log into your site.
password Text The user's password will be encrypted.
salt Int (11) "salt" will be used to encrypt they user's password.
isDeleted Bool A TRUE/FALSE value that will be used to tell if a user has canceld there account or has been blocked.
timestamp Timestamp A time stamp, provided by the database, about time the account was created or last updated.

If you've successfully done our other lesson, User registration, you should have rows in your table that look similar to this:

userID Email Password Salt isDeleted timestamp
1 user@website.com alksjd98f7a3lkj23kjlafg135ge 1579288518 0 2020-01-17 02:15:18
2 user2@website.com iooqiqur798gn3l523nkavf98u 1579288820 0 2020-01-17 02:20:30
3 user3@website.com vx63iv73oulvkj456209v8vj34 1579289122 0 2020-01-17 02:25:42

We will create a form to change the password, then compare the submitted current password against that stored in the database and update it with the new password if things match.

The HTML form

Create a PHP web page file with a form for your users to change their password.

					<html>
						<head>
							<title>Change password</title>
						</head>
						
						<body>
							
							<h1>Change password</h1>
							
							<form action="" method="post">
							
								<p>
									<label for="current_password">Your current password</label>
									<br/>
									<input type="password" name="current_password" id="current_password" />
								</p>
								
								<p>
									<label for="new_password">Your new password</label>
									<br/>
									<input type="password" name="new_password" id="new_password" />
								</p>
								
								<p>
									<button type="submit">Change password</button>
								</p>
								
							</form>
							
						</body>
					</html>
				
Change password form image

With that form, we'll be able to gather the user's current password and new password. Leave the method="post" so the user's submitted data won't be displayed in the URL. We're leaving the action="" blank so the PHP can remain on just this page.

Beginning the PHP

Since we want this page to be accessed by only logged-in users, we must start and verify the $_SESSION values. Refer to our lesson about setting restrictions for information.

The array $_POST will hold the user's submitted information. It is a global variable and is available on the page whether the user has submitted the form or not. To prevent this from processing an empty $_POST, we'll set up a simple if() conditional about the HTML.

					<?php
						session_start();
						
     					// Is the user logged in?
						if(!isset($_SESSION['userID']) || !isset($_SESSION['email'])){
							header('Location: /login.php');
						}
						
						// Did the user submit the form?
						if(!empty($_POST)){
							// Process the form
						}
					?>
					
					<html>
					
					[...]
				

That conditional will prevent anything from happening unless the form is submitted. Next, we'll take the variables out of the $_POST array for use.

Getting the $_POST variables

Once the form is submitted, the $_POST array will be holding the variables from it. The form we have will carry two variables, $_POST['email'] and $_POST['password'].

					<?php
						session_start();
						
     					// Is the user logged in?
						if(!isset($_SESSION['userID']) || !isset($_SESSION['email'])){
							header('Location: /login.php');
						}
						
						// Did the user submit the form?
						if(!empty($_POST)){
							// Process the form
							
							$current_password = $_POST['current_password'];
							$new_password = $_POST['new_password'];
						}
					?>
					
					<html>
					
					[...]
				

Now we have the variables from the $_POST array in separte variables. We could work through the whole process with them in the $_POST array, but htis simplifies it. Next, let's make sure both fields are valid.

Validating the form fields

We want to avoid bad data as often as possible. So, let's make sure the user has submitted real, valid data. Neither the current password nor the new password may be left blank.

PHP has two functions that we will be using. We'll use the function trim() to see if the password was left blank or with only spaces. We'll use function filter_var() to make sure the email address is formatted like an email address. We'll use a conditional if() to judge whether or not the process should continue.

					<?php
						session_start();
						
     					// Is the user logged in?
						if(!isset($_SESSION['userID']) || !isset($_SESSION['email'])){
							header('Location: /login.php');
						}
						
						// Did the user submit the form?
						if(!empty($_POST)){
							// Process the form
							
							$current_password = $_POST['current_password'];
							$new_password = $_POST['new_password'];
							
							$check_current_password = trim($current_password);
							$check_new_password = trim($new_password);
							
							if($check_current_password != '' && $check_new_password != ''){
								// Continue the process
							}
							else {
								$error = 'Please provide both your current password and your new password.';
							}
						}
					?>
					
					<html>
					
					[...]
				

The function trim() removes any spaces at the start and end of the string in $current_password and $new_password.

Notice the variable, $error. We'll use that later on to tell the user something went wrong. If everything went well, we'll get started with a connection to the database.

Connecting with the database

If the user's current and new passwords checked out, let's connect to the database and prepare to change their password. We'll use the PHP built-in class MySQLi to do it. Let's take a look into the if() conditional that approved the email address and password.

					if($check_current_password != '' && $check_new_password != ''){
						// Continue the process
						
						// What's the address of your database?
						$database_host = 'localhost';
						
						// What's the username to connect?
						$database_user = 'root';
						
						// What's the password for that user?
						$database_password = 'password';
						
						// What's the name of the database?
						$database = 'social';
						
						// User the MySQLi class to connect to database
				        $mysqli = new mysqli($database_host, $database_user, $database_password, $database);
						
						$current_password = $mysqli->real_escape_string($current_password);
						$new_password = $mysqli->real_escape_string($new_password);
						
						
						
						// Always close the database connection
						$mysqli->close();
					}
				

Once we had a connection to the database, we were able to use a function built into the class MySQLi, real_escape_string(). That function analyzed the strings and cleaned them up, if necessary, to protect the database from queries a user might be sending. Even though we validated the username and password, We should still sanitize them.

Getting the user information

Now that we know the user has submitted valid data, we want to compare it against the info in the database. We'll query for information about the user depending on the email address they submitted.

					if($check_current_password != '' && $check_new_password != ''){
						/*
							Database connection stuff
						*/
						
						$sql = "SELECT password, salt FROM users WHERE userID='" . $_SESSION['userID'] . "'";
						$query = $mysqli->query($sql);
						
						$pass = $query->fetch_assoc();
						
						
						
						
						
						// Always close the database connection
						$mysqli->close();
					}
				

The query is asking for the encrypted password and salt from the user with an ID number matching that in their $_SESSION. The variable $_SESSION['userID'] was generated in the log-in process. Then, we're using the MySQLi class function, fetch_assoc(), to get that information into an array.

The variable, $pass, is now an array containing the user's encrypted password and salt. If you want to see what is in $pass, enter print_r($pass); under the variable. The array looks similar to this:

					 Array
						(
							[password] => alksjd98f7a3lkj23kjlafg135ge
							[salt] => 1408705391
						)
				

Comparing the passwords

In a different lesson, User registration, we went over a way to encrypt the user's password by salting it with another variable. We stored the salt in the database next to the encrypted password. Let's attach the salt to the password the user submitted, encrypt it, and then compare it against the encrypted password in the database.

To get to the stored salt, we need to use $user['salt']. To get to the stored password, we need to use $user['password'].

					if($check_password != '' || $check_email !== FALSE){
						/*
							Database connection stuff
							
							Table query
						*/
						
						$pass = $query->fetch_assoc();
						
						$salt = $pass['salt'];
						
						// Does their $current_password, while encrypted, match their database password?
						$encrypt_current_password = sha1($current_password . $salt);
						
						if($encrypt_current_password == $pass['password']){
							// Password matches. Continue to change password.
						}
						else {
							$error = 'Incorrect information. Please try again.';
						}
						
						
						
						
						// Always close the database connection
						$mysqli->close();
					}
				

Just as we did in a different lesson, User registration, encrypted the password the user submitted by salting it with another variable, the one provided by the database, and compared the encrypted version.

If the encrypted versions match, the user is valid and we should allow them in to change their password.

Changing the password

To change the user's password, we need to update their row in the database table users. We need to make new salt and encrypt their new password.

					if($encrypt_current_password == $pass['password']){
						$new_salt = time();
						
						$encrypt_new_password = sha1($new_password . $new_salt);
						
						$sql = "UPDATE users SET password='" . $encrypt_new_password . "', salt=" . $new_salt . " WHERE userID=" . $_SESSION['userID'];
						$query = $mysqli->query($sql);
						
						$error = 'Successfully updated your password.';
					}
					else {
						$error = 'Incorrect information. Please try again.';
					}
				

We have updated the user with userID equal to the $_SESSION['userID'] to have a new password with new salt.

What if there were errors or success?

The user may have submitted invalid data, their password may not have matched that in the database or the could have completed it successfully. Let's use the $error variable we created to deliver the message on the web page.

					<html>
						<head>
							<title>Change password</title>
						</head>
						
						<body>
							
							<h1>Change password</h1>
							
							<?php if(isset($error)): ?>
								

<?php echo $error; ?>

<?php endif; ?> <form action="" method="post"> <p> <label for="current_password">Your current password</label> <br/> <input type="password" name="current_password" id="current_password" /> </p> <p> <label for="new_password">Your new password</label> <br/> <input type="password" name="new password" id="new_password" /> </p> <p> <button type="submit">Change password</button> </p> </form> </body> </html>

Change password error message image

Change password error message image

Change password success message image

All the code

					<?php
						session_start();
						
     					// Is the user logged in?
						if(!isset($_SESSION['userID']) || !isset($_SESSION['email'])){
							header('Location: /login.php');
						}
						
						// Did the user submit the form?
						if(!empty($_POST)){
							// Process the form
							
							$current_password = $_POST['current_password'];
							$new_password = $_POST['new_password'];
							
							$check_current_password = trim($current_password);
							$check_new_password = trim($new_password);
							
							if($check_current_password != '' && $check_new_password != ''){
								// Continue the process
								
								// What's the address of your database?
								$database_host = 'localhost';
								
								// What's the username to connect?
								$database_user = 'root';
								
								// What's the password for that user?
								$database_password = 'password';
								
								// What's the name of the database?
								$database = 'social';
								
								// User the MySQLi class to connect to database
								$mysqli = new mysqli($database_host, $database_user, $database_password, $database);
								
								$current_password = $mysqli->real_escape_string($current_password);
								$new_password = $mysqli->real_escape_string($new_password);
								
								$sql = "SELECT password, salt FROM users WHERE userID='" . $_SESSION['userID'] . "'";
								$query = $mysqli->query($sql);
								
								$pass = $query->fetch_assoc();
								
								$salt = $pass['salt'];
								
								// Does their $current_password, while encrypted, match their database password?
								$encrypt_current_password = sha1($current_password . $salt);
								
								if($encrypt_current_password == $pass['password']){
									$new_salt = time();
									
									$encrypt_new_password = sha1($new_password . $new_salt);
									
									$sql = "UPDATE users SET password='" . $encrypt_new_password . "', salt=" . $new_salt . " WHERE userID=" . $_SESSION['userID'];
									$query = $mysqli->query($sql);
									
									$error = 'Successfully updated your password.';
								}
								else {
									$error = 'Incorrect information. Please try again.';
								}
								
								
								
								// Always close the database connection
								$mysqli->close();
							}
							else {
								$error = 'Please provide both your current password and your new password.';
							}
						}
					?>
					
					<html>
						<head>
							<title>Change password</title>
						</head>
						
						<body>
							
							<h1>Change password</h1>
							
							<?php if(isset($error)): ?>
								

<?php echo $error; ?>

<?php endif; ?> <form action="" method="post"> <p> <label for="current_password">Your current password</label> <br/> <input type="password" name="current_password" id="current_password" /> </p> <p> <label for="new_password">Your new_password</label> <br/> <input type="password" name="new_password" id="new_password" /> </p> <p> <button type="submit">Change password</button> </p> </form> </body> </html>

Contact us

Questions or problems? Want to contribute to this tutorial or others?

Contact us