manuelklerk Posted July 22, 2023 Share Posted July 22, 2023 The code is supposed to insert the form data in the readers table in a database called travpress. the database connection is correct but the form on input nothing is summited to the database table also no error is shown. Thank you <?php // require '../database/dbcon.php'; // require_once('functions.php'); // db con $host = 'localhost'; $username = 'root'; $password = ''; $database = 'travpress'; $connection = new mysqli($host, $username, $password, $database); if ($connection->connect_error) { die("Connection failed: " . $connection->connect_error); } // Function to sanitize input data function sanitize($data) { return htmlspecialchars(stripslashes(trim($data))); } // Function to validate email format function validateEmail($email) { return filter_var($email, FILTER_VALIDATE_EMAIL); } // Function to generate CSRF token function generateCSRFToken() { if (session_status() == PHP_SESSION_NONE) { session_start(); } $token = bin2hex(random_bytes(32)); $_SESSION['csrf_token'] = $token; return $token; } // Function to verify CSRF token function verifyCSRFToken($token) { if (session_status() == PHP_SESSION_NONE) { session_start(); } return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token); } // Function to handle file upload and return the uploaded file path function uploadProfilePhoto($file) { $targetDir = '../uploads/'; $targetFile = $targetDir . basename($file['name']); $imageFileType = strtolower(pathinfo($targetFile, PATHINFO_EXTENSION)); // Check if it's an actual image $check = getimagesize($file["tmp_name"]); if ($check === false) { return false; } // Check file size (maximum 2 MB) if ($file["size"] > 2097152) { return false; } // Allow only certain image file formats if ($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg" && $imageFileType != "gif") { return false; } if (move_uploaded_file($file['tmp_name'], $targetFile)) { return $targetFile; } else { return false; } } // Check if the form is submitted and the CSRF token is valid if (isset($_POST["submit"]) && verifyCSRFToken($_POST['csrf_token'])) { // Sanitize and retrieve form data $first_name = sanitize($_POST['first_name']); $last_name = sanitize($_POST['last_name']); $username = sanitize($_POST['username']); $email = sanitize($_POST['email']); $phone = sanitize($_POST['phone']); $location = sanitize($_POST['location']); $gender = sanitize($_POST['gender']); $password = $_POST['password']; $confirm_password = $_POST['confirm_password']; // Validate email if (!validateEmail($email)) { echo "Invalid email format!"; exit; } // Check if the passwords match if ($password !== $confirm_password) { echo "Passwords do not match!"; exit; } // Hash the password using bcrypt (password_hash with PASSWORD_DEFAULT) $hashed_password = password_hash($password, PASSWORD_DEFAULT); // Upload the profile photo if (isset($_FILES['profilephoto']) && $_FILES['profilephoto']['error'] === 0) { $profile_photo = uploadProfilePhoto($_FILES['profilephoto']); if (!$profile_photo) { echo "Error uploading the profile photo!"; exit; } } else { echo "Profile photo upload failed!"; exit; } // Prepare the SQL query using prepared statements to prevent SQL injection $stmt = $connection->prepare("INSERT INTO readers (first_name, last_name, username, email, phone, location, gender, profilephoto, password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->bind_param("sssssssss", $first_name, $last_name, $username, $email, $phone, $location, $gender, $profile_photo, $hashed_password); // Execute the query if ($stmt->execute()) { // Registration successful, redirect to the login page header("Location: reader-login.php"); exit; } else { echo "Error: " . $stmt->error; } // Close the prepared statement $stmt->close(); } ?> <!DOCTYPE html> <html> <head> <title>TravPress- Registration</title> <style> body { color: #000; font-family: Arial, sans-serif; font-size: 16px; margin: 0; padding: 0; text-align: center; } form { background-color: #00A388; border-radius: 8px; box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.3); box-sizing: border-box; margin: 40px auto; max-width: 600px; padding: 40px; text-align: left; } h3 { color: #00A388; font-size: 2rem; text-align: center; font-weight: bold; margin-bottom: 30px; text-shadow: 2px 2px #fff; } input[type="text"], input[type="email"], input[type="tel"], input[type="file"], input[type="password"] { background-color: #fff; border: none; border-radius: 4px; box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.3); box-sizing: border-box; display: block; margin-bottom: 20px; padding: 10px; width: 100%; } label[for="gender"] { display: block; margin-bottom: 10px; color: black; } /* Style for the select */ select[name="gender"] { display: block; width: 100%; padding: 10px; border: none; border-radius: 4px; box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.3); background-color: #fff; color: #333; } input[type="submit"] { background-color: #000; border: none; border-radius: 4px; color: #fff; cursor: pointer; display: block; font-size: 1.2rem; font-weight: bold; margin-top: 30px; padding: 10px; text-align: center; width: 100%; } </style> </head> <body> <form action="reader-reg.php" method="POST" enctype="multipart/form-data"> <header> <h3>Create a TravPress account below</h3> </header> <label for="first_name">First Name:</label> <input type="text" name="first_name" required> <label for="last_name">Last Name:</label> <input type="text" name="last_name" required> <label for="username">Username: <p style="font-size: 10px; color: yellow;">Will be used as your author name in case you make a publication.</p></label> <input type="text" name="username" required> <label for="email">Email:</label> <input type="email" name="email" required> <label for="phone">Phone:</label> <input type="tel" name="phone" required> <label for="location">Location:</label> <input type="text" name="location" required> <label for="gender">Gender:</label> <select name="gender" style="margin-bottom: 20px;" required> <option value="male">Male</option> <option value="female">Female</option> <option value="other">Other</option> </select> <label for="image">User Image:</label> <input type="file" name="profilephoto" required> <label for="password">Password:</label> <input type="password" name="password" required> <label for="confirm_password">Confirm Password:</label> <input type="password" name="confirm_password" required> <input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>"> <input type="submit" value="Register"> <p>Already Registered? login to your account <span style="text-decoration: underline;"><a href="reader-login.php">Here</a></p></small> </form> </body> </html> Quote Link to comment Share on other sites More sharing options...
Barand Posted July 22, 2023 Share Posted July 22, 2023 Put this line just before you create $connection... mysqli_report(MYSQLI_REPORT_ERROR|MYSQLI_REPORT_STRICT); ... to report any problems with your queries. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted July 22, 2023 Share Posted July 22, 2023 (edited) what conditions are necessary for your post method form processing code to run? have you checked what values they are? you can use echo '<pre>'; print_r($_POST); to see what the submitted post data is. next, you should NOT attempt to detect if the submit button isset(). there are cases where it won't be. you should instead detect if a post method form was submitted. one such case is if the total size of the form data exceeds the post_max_size setting on the server. in this case, both the $_POST and $_FILES arrays will be empty. after you detect if a post method form was submitted, you should detect this condition and setup a message for the user that the form data was too large (typically due to the size of the uploaded file) and could not be processed. you should also not combine the tests for multiple inputs together into one conditional statement, as this makes error checking and handling/logging difficult. if the CSRF token doesn't match, you would want to display, during development, or log, when on a live/public server, information about the occurrence of that error. there's a bunch of issues with the code that should be addressed - don't output database statement - connection, query, prepare, and execute errors onto a live web page. after you add the line of code that @Barand posted above, to use exceptions for errors for the mysqli extension, remove any existing conditional database error handling logic you have since it will no longer get executed upon an error. don't use the root database user without a password for your applications. create a specific database user, with a password. with only the database permissions that your application needs. delete the sanitize function you have now. you should only trim, then validate input data. htmlspecialchars() is an output function. it is applied when you output data in a html context, right before you output the data. do not use it on input data in your post method form processing code. stripslashes(), when it was needed, was conditionally applied, when magic_quotes_gpc was ON. the need to do this was removed from php a long time ago (deprecated as of PHP 5.3.0 and removed in PHP 5.4. in 2012) client side validation is a nicety for legitimate visitors. you must (trim, then) validate all input data on the server before using it. don't create discrete variables for every input. this is just a waste of typing. instead, keep the (POST) form data as a set, in a php array variable, then use elements in this array variable throughout the rest of the code. once you do item #5 on this list, you can trim all the input data at once using one single line of code. validate each input separately, storing user/validation errors in an array using the field name as the main array index. what you are doing now, by echoing and exiting on each validation error, the user will need to keep resubmitting the form until all the validation errors have been corrected. the uploadProfilePhoto() function should setup a unique and helpful error message for each different problem that will prevent the uploaded file from being used, i.e. don't make the user guess why something they did, failed. after the end of all the validation logic, if there are no errors (the array holding the user/validation errors will be empty), use the submitted form data. the username and email columns must not contain duplicate values. these two columns must be defined as unique indexes. you would then have exception try/catch logic for this insert query, where you would test if the error number is for a duplicate index error, then setup a message for the user (add it to the array holding the user/validation errors), letting them know what was wrong with the data that they submitted. for all other error numbers, just re-throw the exception and let php handle it. after the end of using the submitted form data, if there are still no errors, you would redirect to the exact same url of the current page to cause a get request for that page. this will prevent the browser from trying to resubmit the form data if the page is reloaded or browsed away from and back to. to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate location in the html document. if there are errors at item #9 or #11 on this list, the code will continue on to display the html document, where you would test for and display any errors in the array holding the user/validation errors, redisplay the form, and populate the form field values/selected options with the existing data, so that the user doesn't need to keep reentering data over and over upon each validation error. it is at this point where you would apply htmlentities() to the values being output on the web page. in most cases, there's no need to close prepared statements, free up result sets, of close database connections, since php automatically destroys all the resources on a page when your script ends. you need to validate your resulting web pages at validator.w3.org there are errors concerning the <label> tags, the 1st required option choice, stray markup, ... to get a form to submit to the same page it is on, simply leave out the entire action attribute. Edited July 22, 2023 by mac_gyver Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.