below is simple PHP script to validate and successfully submit the form to the server I've added xhr(XMLHttpRequest) to make it efficient.First it was supposed to check if the input fields are empty then show error message , if password does not meet criteria then show error message but i am wondering why it does not work like it was expected , when i click submit button it submit the form and none of the functionalities works . any help will be appreciated
<?php
require_once('db.php');
error_reporting(~E_NOTICE);
date_default_timezone_set('Africa/Nairobi');
// Log errors to a file
ini_set('error_log', '/var/log/php_errors.log');
// Initialize error message array
$errMsg = array();
if(isset($_POST['register'])){
$name = filter_var($_POST['name'], FILTER_SANITIZE_STRING);
$password = filter_var($_POST['password'], FILTER_SANITIZE_STRING);
$time=date('y-m-d h:i:s',time());
$date=date('y-m-d',strtotime('now'));
// validate inputs and Display user-friendly error messages
if (empty($name) || empty($password)) {
// Display error message to the user
$errMsg[] = "Enter both name and password";
} else{
// Implement password complexity rules
if (strlen($password) < 8 || !preg_match("#[0-9]+#", $password) || !preg_match("#[A-Z]+#", $password) || !preg_match("#[a-z]+#", $password) || !preg_match("#[\W]+#", $password)) {
$errMsg[]="Password must contain at least 8 characters including uppercase and lowercase letters, numbers, and symbols";
} else {
// Use a custom salt instead of the default salt
$custom_salt = bin2hex(random_bytes(10));
// Use password_hash() function to create a password hash
$hash = password_hash($password . $custom_salt, PASSWORD_BCRYPT);
// Insert user details into database
if(empty($errMsg)){
$sth=$db->prepare("INSERT INTO users(name,password,time,date) VALUES(:name,:password,:time,:date)");
$sth->bindParam(':name', $name, PDO::PARAM_STR);
$sth->bindParam(':password', $hash, PDO::PARAM_STR);
$sth->bindParam(':time', $time, PDO::PARAM_STR);
$sth->bindParam(':date', $date, PDO::PARAM_STR);
$sth->execute();
die('success');
}
}
}
}
?>
<!-- HTML code starts here -->
<!DOCTYPE html>
<html>
<head>
<title>User Registration</title>
</head>
<body>
<h2>User Registration Form</h2>
<?php
// Display error messages
if (!empty($errMsg)) {
foreach ($errMsg as $msg) {
echo '<div style="color: red;">' . $msg . '</div>';
}
}
?>
<div id="error-message" style="color: red;"></div>
<form id="register-form" action="" method="post">
<label for="name">Name:</label>
<input type="text" id="name" name="name"><br><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password"><br><br>
<input type="submit" name="register" value="Register">
</form>
<script>
const form = document.getElementById('register-form');
form.addEventListener('submit', function(event) {
event.preventDefault(); // prevent the default form submission
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
// successful response, redirect to the index page
window.location.href = 'index.php';
} else {
// display the error message to the user
const errMsg = document.getElementById('error-message');
errMsg.innerHTML = xhr.responseText;
}
}
};
xhr.open('POST', form.action);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(new FormData(form));
});
</script>
</body>
</html>
You have at least two different problems here, each of which would cause your problem by itself.
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.send(new FormData(form));
Under normal circumstances, when you pass a FormData
object to send()
then XHR will generate a Content-Type
request header from it with the correct content type (multipart form data with a boundary parameter).
In this case you've overridden the Content-Type
header to one that is wrong. PHP tries to parse the body as application/x-www-form-urlencoded
, fails, and doesn't populate $_POST
.
isset($_POST['register'])
When you submit a form normally, the clicked submit button becomes a successful control (i.e. sends its name and value in the form data).
You're intercepting the normal form submission (and preventing it with event.preventDefault();
) and constructing a new request using Ajax.
new FormData(form)
will not include the submit button's data, so you can't use it to branch your code with an if
statement as you are attempting.