The below quick example validates the password field values posted via a form. First, it checks if both the password fields are not empty. Then, it applies a regex-based condition to validate the passwords.
This example uses a pattern and it is a regular expression. The PHP preg_match
function returns a boolean if the entered password is matched with this pattern.
This password validation returns true if the entered password has at least 1 uppercase, lowercase, number and special character and with a minimum 8-character length.
This is a password strength checker tool for a PHP application. In a previous tutorial, we created a password strength checker in jQuery.
<?php
$passwordError = "";
if (!empty($_POST["password"]) && !empty($_POST["confirm_password"])) {
$password = htmlspecialchars($_POST["password"]);
$confirmPassword = htmlspecialchars($_POST["confirm_password"]);
// Password pattern that is to find match containing
// at least 1 uppercase, lowercase, number and special characters
// and also length 8
$password_pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/';
if ($password != $confirmPassword) {
$passwordError .= "Passwords are not same.\n";
}
if (!preg_match($password_pattern, $password)) {
$passwordError .= "Password must have at least 8 character length with mimimum 1 uppercase, 1 lowercase, 1 number and 1 special characters.\n";
}
} else {
$passwordError .= "Enter password and confirm.\n";
}
// Prepare validation response for acknowleding user
if (!empty($passwordError)) {
$validationOutput = array("type" => "error", "ack" => nl2br($passwordError));
} else {
$validationOutput = array("type" => "success", "ack" => "Password is valid.");
// Handle further processing once the password is validated
}
require_once __DIR__ . "/inc/password-form.inc";
?>
This example requires the password form code to display the password fields to the browser. The HTML for the password form is included in this article.
The above example prepares the response array with the validation output. The form UI displays the validation response to acknowledge the user.
This example code is a slight variation of the above quick example. It built an if-else ladder to apply a round password validation process. The type of strength validations made in PHP are listed below.
Once the 4 conditions returns true, then the PHP validation script prepare the success message “Password is valid.”
Otherwise, a PHP array is created with lines password validation errors occurred.
This example returns relevant errors related to what is missing in the entered password. But, in the quick example, it always shows the same error.
validation-ladder.php
<?php
$passwordError = "";
if (!empty($_POST["password"]) && !empty($_POST["confirm_password"])) {
$password = htmlspecialchars($_POST["password"]);
$confirmPassword = htmlspecialchars($_POST["confirm_password"]);
if ($password != $confirmPassword) {
$passwordError .= "Passwords are not same.\n";
}
if (strlen($password) <= 8) {
$passwordError .= "Password must have 8 characters at least.\n";
}
if (!preg_match("#[0-9]+#", $password)) {
$passwordError .= "Password must have 1 Number at least.\n";
}
if (!preg_match("#[A-Z]+#", $password)) {
$passwordError .= "Password must have 1 uppercase letter at least.\n";
}
if (!preg_match("#[a-z]+#", $password)) {
$passwordError .= "Password must have 1 lowercase letter at least.\n";
}
} else {
$passwordError .= "Enter password and confirm.\n";
}
// Prepare validation response for acknowleding user
if (!empty($passwordError)) {
$validationOutput = array("type" => "error", "ack" => nl2br($passwordError));
} else {
$validationOutput = array("type" => "success", "ack" => "Password is valid.");
}
require_once __DIR__ . "/inc/password-form.inc";
?>
Since the password is masked with the type=password
attribute, a “View Password” option along with the error might help to find the mistake.
The password strength validation code is same in this example as like as the quick example we have seen very first. But, the error message banner has a “View Password” button.
On clicking this button, it toggles the password type between type=password
and type=text
.
The toggling JavaScript and the View Password button are not in the password form HTML page. Rather, the script is dynamically enqueued from the PHP when returning the error.
We have used the dynamic script/styles enqueueing method very often when working with WordPress. When integrating WooCommerce shop, the theme function.php does enqueueing shop styles and JS.
validation-with-view-password-enable-disable.php
<?php
if (!empty($_POST["validate_password"])) {
$passwordError = "";
if (!empty($_POST["password"]) && !empty($_POST["confirm_password"])) {
$password = htmlspecialchars($_POST["password"]);
$confirmPassword = htmlspecialchars($_POST["confirm_password"]);
$password_pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/';
if ($password != $confirmPassword) {
$passwordError .= "Passwords are not same.\n";
}
if (!preg_match($password_pattern, $password)) {
$passwordError .= "Password must have at least 8 character length with mimimum 1 uppercase, 1 lowercase, 1 number and 1 special characters.\n";
}
} else {
$noPassword = true;
$passwordError .= "Enter password and confirm.\n";
}
// Prepare validation response for acknowleding user
if (!empty($passwordError)) {
$validationOutput["type"] = "error";
if ($noPassword) {
$validationOutput["ack"] = nl2br($passwordError);
} else {
$btnViewPassword = "<button type='button' class='btn-view-password' onClick='
document.querySelectorAll(\".password-input\").forEach(el =>
(el.type == \"password\") ? (el.type = \"text\") : (el.type = \"password\")
); '>
View password</button>";
$validationOutput["ack"] = nl2br($passwordError) . $btnViewPassword;
$validationOutput["re_populate"] = true;
}
} else {
$validationOutput = array("type" => "success", "ack" => "Password is valid.");
// Handle further processing once the password is validated
}
}
require_once __DIR__ . "/inc/password-form.inc";
?>
This code is for displaying the password and the confirm password fields to the UI. It is in a HTML form which post the entered password to the PHP for a strength validation.
This HTML includes a container to show the acknowledgement message to the user. It is regarding result of the strength checking took place on the PHP side.
inc/password-form.inc
<?php
function rePopulatePassword($validationOutput, $password)
{
if (isset($validationOutput["re_populate"])) {
echo $password;
}
}
?>
<html>
<head>
<title>Change Password</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/form.css" />
<style>
.page-top-spacing {
margin-top: 60px;
}
.btn-view-password {
background-color: #2cd1ff;
border-color: #8ebfff70 #3da2ff00 #007ede30;
margin: 20px 0px 10px 0px;
}
</style>
</head>
<body>
<h2 class="text-center page-top-spacing">PHP Password Strength Validator</h2>
<div class="phppot-container tile-container">
<form name="frmChange" method="post" action="" onSubmit="return validatePassword()">
<div>
<div class="row">
<label class="inline-block">New Password</label>
<input type="password" name="password" class="password-input full-width" value="<?php if (!empty($_POST["password"])) {
rePopulatePassword($validationOutput, $_POST["password"]);
} ?>">
</div>
<div class="row">
<label class="inline-block">Confirm Password</label>
<input type="password" name="confirm_password" class="password-input full-width" value="<?php if (!empty($_POST["password"])) {
rePopulatePassword($validationOutput, $_POST["confirm_password"]);
} ?>">
</div>
<div class="row">
<input type="submit" name="validate_password" value="Submit" class="full-width">
</div>
</div>
</form>
</div>
<?php if (isset($validationOutput)) { ?>
<div class="phppot-message phppot-container <?php echo $validationOutput["type"]; ?>"><?php echo $validationOutput["ack"]; ?></div>
<?php } ?>
</body>
</html>