Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 06/26/2025 in all areas

  1. The validation fails because the file containing the validation logic is never executed when the form is submitted. The standard and most effective solution is to handle everything in one file. The form page should be responsible for: Displaying the form. Receiving the submitted data. Validating the data. If invalid, re-displaying the form with errors. If valid, performing the final action (like sending an email). You just need to move the email-sending logic from form.php into the else block of your validation file. Here is the corrected and combined code. You can replace the entire contents of your first file with this. You will no longer need form.php at all. <?php // 1. SETUP $user = ['name' => '', 'age' => '']; $errors = ['name' => '', 'age' => '']; $message = ''; $form_submitted_successfully = false; // A flag to know when to hide the form // 2. PROCESS FORM IF SUBMITTED if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Validation filters $validation_filters['name']['filter'] = FILTER_VALIDATE_REGEXP; $validation_filters['name']['options']['regexp'] = '/^[A-z]{2,10}$/'; $validation_filters['age']['filter'] = FILTER_VALIDATE_INT; $validation_filters['age']['options']['min_range'] = 16; $validation_filters['age']['options']['max_range'] = 65; $user_input = filter_input_array(INPUT_POST, $validation_filters); // Create error messages $errors['name'] = $user_input['name'] ? '' : 'Name must be 2-10 letters using A-z'; $errors['age'] = $user_input['age'] ? '' : 'You must be between 16 and 65'; // Sanitize the original POST data to redisplay it safely in the form $user['name'] = filter_var($_POST['name'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); $user['age'] = filter_var($_POST['age'], FILTER_SANITIZE_NUMBER_INT); // Check if there are any errors by joining all error messages $invalid = implode($errors); // 3. DECIDE WHAT TO DO NEXT if ($invalid) { // If there are errors, show an error message $message = 'Please correct the following errors:'; } else { // If data is valid, SEND THE EMAIL $to = '[email protected]'; // Use a real email address $subject = 'Contact Form Submission'; $msg = "Name: {$user['name']}\n" . "Age: {$user['age']}\n"; $headers = 'From: [email protected]'; // It's good practice to set a From header // The mail() function returns true on success, false on failure if (mail($to, $subject, $msg, $headers)) { $message = 'Thank you, your data has been sent!'; $form_submitted_successfully = true; // Set flag to true } else { $message = 'Sorry, there was an error sending your message. Please try again later.'; } } } ?> <?php // include 'includes/header.php'; // Assuming you have this file ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Validation Form</title> <style> .error { color: red; font-size: 0.8em; display: block; } body { font-family: sans-serif; } input { margin-bottom: 10px; } form { border: 1px solid #ccc; padding: 20px; max-width: 400px; } .message { padding: 10px; background-color: #e0e0e0; margin-bottom: 15px; } </style> </head> <body> <h1>Contact Us</h1> <?php if ($message): ?> <p class="message"><?= $message ?></p> <?php endif; ?> <?php // Only show the form if it hasn't been submitted successfully if (!$form_submitted_successfully): ?> <form name="form" action="" method="POST"> Name: <input type="text" name="name" value="<?= htmlspecialchars($user['name']) ?>"> <span class="error"><?= $errors['name'] ?></span><br> Age: <input type="text" name="age" value="<?= htmlspecialchars($user['age']) ?>"> <span class="error"><?= $errors['age'] ?></span><br> <input type="submit" value="Submit"> </form> <?php endif; ?> </body> </html>
    1 point
  2. the code for every page (http request) must enforce what the current user can do or see on that page. if you do what i wrote in one of your recent threads - the code performing the admin actions will find that the current user is either not logged in, doesn't exist, or no longer has a role that allows access to the code on that page and the user will be prevented from performing any action.
    1 point
  3. here are some implementation practices - the form processing code and form should be on the same page. by putting them on separate pages, you are creating a lot of extra code. by only validating one input at a time and not having the form fields 'sticky', you are providing a poor User eXperience (UX). by storing the 'login_attempts' and 'lockout_time' in session variables, a nefarious user/bot can get unlimited new login attempts by simply not propagating the session id cookie between requests. you must store this data persistently on the server in a database table. the only user related value you should store in a session variable upon successful login is the user id (autoincrement primary index.) you should query on each page request to get any other user data, so that any changes made to the user data will take effect on the very next page request, without requiring the user to log out and back in again. the way a 'remember me' operation should be implemented is that if the remember me checkbox is checked, at the point of successfully verifying the user's credentials, generate a unique token, store that in a cookie and in a database 'remember me' table that also includes the user id, and the current datatime, for a determining token expiration. on any page request, if the remember me token cookie is set, query to find a matching row in the remember me table. if there is a row and the token is not timed out, use the user id from that row to set the session variable that identifies who the logged in user is. the rest of the code then uses this value in the session variable, just like it was set in the login form processing code. the registration process, unless being performed by an administrator, which your code is not doing, should not include the role. the role should not be something that the user can decide when they register. modern php (8+) uses exceptions for database statement errors by default - connection, query, prepare, and execute. any discrete logic you currently have testing the result of these statements should be removed since it will never get executed upon an error. both the username and email must be unique or you should only use the email and forget about a separate username. the correct way of determining if a unique value already exists in a database table is to define the column(s) as a unique index, just attempt to insert the data, and detect in the exception catch logic for the insert query if a duplicate index error (number) occurred. any form processing code should keep for the form data as a set, in an array variable, then operate on elements in this array variable throughout the rest of the code. i.e. don't write out a line of code copying every $_POST variable to a discrete variable. you need to trim ALL the user supplied inputs, mainly so that you can detect if all white-space characters were entered, before validating the data. you need to use an array to hold user/validation errors, and validate all the inputs at once, storing the errors in the array using the field name as the array index. after the end of the validation logic, if there are no errors (the array will be empty), use the submitted form data. in the login validation logic, all you really care about is that the required inputs are are not empty strings, after being trimmed. by providing additional feedback to a nefarious user/bot, you are helping narrow down the values they need to try.
    1 point
  4. the above line is missing any { }, so the only line of code that gets executed for an is_dir() is the - echo '<strong>'.$directory .'</strong> <br>'; all the rest of the lines get executed regardless of what $directory is. i recommend that you always format your code so that you can see when it is actually doing.
    1 point
  5. if you use a cookie or the session to hold this data, it can be bypassed by simply deleting the cookie or not propagating the cookie or session id cookie between requests. you must store this data persistently on the server, in a database table. next, you are not trying to lock the account, you are preventing login attempts for an account, from a device (client type) and its location (ip). if you actually lock the account, it will allow someone to log out and lock out a legitimate user, by just making a bunch of bad login attempts for an account. once you have stored the data in a database table, on each login attempt, you would query to find if, how many, and how long ago the bad login attempts were for the account, for the device (client type) and its location (ip). If the current time is greater than the time limit you have chosen from the last bad attempt, you would process the login attempt.
    1 point
  6. "Revolution"? lol. It's another Whatever from the tech world. It's not the first fad used to pump up stock prices, and it won't be the last. The current state of glorified autocomplete systems AI contributes just about as much value to the world as The Blockchain does. You remember that whole thing? Wasn't that long ago when The Blockchain was being called a "revolution" too... The next Whatever will happen in a few weeks, or months, or years, and every publicly-traded company will jump on that as fast as they can too. (Make sure you're not still holding onto all of your NVDA when that happens.) And I'm sure that'll bring its own "revolution" too.
    1 point
  7. Done this for many systems: 100% agree with Barand. I will go one step further and make this an "event" table where the system can insert rows for other events. Off the top of my head other events (in an event_type table or enum) would be a list like this: login logout bad password attempt change password reset password request etc. A simple table like this is common, has and has the benefit (with proper indexing) of allowing for the types of analysis and controls Barand listed. It also allows for mitigating brute force password attempts, as you can use this table to limit the number of login attempts within a given time period for a specific user, and lock the account after a certain number of attempts. Beyond the relationship to the User table (by Id) and a timestamp, you also typically want to store the IP address of the client. If it's mysql, the best way to do this (and natively support both IPv4 and IPv6) is to store the IP as VARBINARY(16) and use the INET6_ATON() and INET6_NTOA() functions to convert the IP when storing and retrieving. Small tables like this, with a clear design scale very well, as MySQL/MariaDB (using the InnoDB engine) is tuned to maximize Select & Insert concurrency. Often people will attempt to use a column or 2 in the user table, which they repeatedly update (ie. "last_login") which reduces concurrency, and is also less valuable than having a full history.
    1 point
  8. Logging every login by a registered user is the favoured option. Not only does it give you an audit trail of the logins but it adds functionality, such as being able to count logins in different time periods or determine most popular login times etc.
    1 point
  9. One thing that might be helpful is to use the declare to wrap the block of code you want to have evaluated for statement processing. $count = 0; function statements() { global $count; $count++; echo "Statement Count: $count\n"; } register_tick_function('statements'); declare(ticks=5) { for ($x = 0; $x < 10; $x++) { echo "\$x = $x \n"; } } And you get: $x = 0 $x = 1 $x = 2 $x = 3 $x = 4 Statement Count: 1 $x = 5 $x = 6 $x = 7 $x = 8 $x = 9 Statement Count: 2
    1 point
  10. E_DEPRECATED and E_USER_DEPRECATED are the same thing, with the one difference that the former is used by the engine and the latter is used by trigger_error. So the question is in what environments do you care/not care about getting messages about using deprecated features and functionality?
    1 point
  11. First, click on the error notification and sort out the error. Then try again.
    1 point
  12. I would suggest using Intervention Library as it makes handling images so much easier. I use the following for my own website -> <?php // Include the configuration file and autoload file from the composer. require_once __DIR__ . '/../config/clearwebconfig.php'; require_once "vendor/autoload.php"; use Intervention\Image\ImageManagerStatic as Image; // Import the ErrorHandler and Database classes from the clearwebconcepts namespace. use clearwebconcepts\{ ErrorHandler, Database, ImageContentManager, LoginRepository as Login }; $errorHandler = new ErrorHandler(); // Register the exception handler method set_exception_handler([$errorHandler, 'handleException']); $database = new Database(); $pdo = $database->createPDO(); $checkStatus = new Login($pdo); // To check for either 'member' or 'sysop' if ($checkStatus->check_security_level(['sysop'])) { // Grant access } else { // Access denied header('location: dashboard.php'); exit(); } function is_ajax_request(): bool { return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest'; } $save_result = false; if (($_SERVER['REQUEST_METHOD'] === 'POST') && isset($_FILES['image'])) { $data = $_POST['cms']; $data['content'] = trim($data['content']); $errors = array(); $exif_data = []; $file_name = $_FILES['image']['name']; // Temporary file: $file_size = $_FILES['image']['size']; $file_tmp = $_FILES['image']['tmp_name']; $thumb_tmp = $_FILES['image']['tmp_name']; $file_type = $_FILES['image']['type']; $file_ext = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION)); /* * Set EXIF data info of image for database table that is * if it contains the info otherwise set to null. */ if ($file_ext === 'jpeg' || $file_ext === 'jpg') { $exif_data = exif_read_data($file_tmp); if (array_key_exists('Make', $exif_data) && array_key_exists('Model', $exif_data)) { $data['Model'] = $exif_data['Make'] . ' ' . $exif_data['Model']; } if (array_key_exists('ExposureTime', $exif_data)) { $data['ExposureTime'] = $exif_data['ExposureTime'] . "s"; } if (array_key_exists('ApertureFNumber', $exif_data['COMPUTED'])) { $data['Aperture'] = $exif_data['COMPUTED']['ApertureFNumber']; } if (array_key_exists('ISOSpeedRatings', $exif_data)) { $data['ISO'] = "ISO " . $exif_data['ISOSpeedRatings']; } if (array_key_exists('FocalLengthIn35mmFilm', $exif_data)) { $data['FocalLength'] = $exif_data['FocalLengthIn35mmFilm'] . "mm"; } } else { $data['Model'] = null; $data['ExposureTime'] = null; $data['Aperture'] = null; $data['ISO'] = null; $data['FocalLength'] = null; } $data['content'] = trim($data['content']); $extensions = array("jpeg", "jpg", "png"); if (in_array($file_ext, $extensions, true) === false) { $errors[] = "extension not allowed, please choose a JPEG or PNG file."; } if ($file_size >= 58720256) { $errors[] = 'File size must be less than or equal to 42 MB'; } /* * Create unique name for image. */ $image_random_string = bin2hex(random_bytes(16)); $image_path = 'assets/image_path/img-entry-' . $image_random_string . '-2048x1365' . '.' . $file_ext; $thumb_path = 'assets/thumb_path/thumb-entry-' . $image_random_string . '-600x400' . '.' . $file_ext; move_uploaded_file($file_tmp, $image_path); move_uploaded_file($thumb_tmp, $thumb_path); // Load the image $image = Image::make($image_path); // Resize the image $image->resize(2048, 1365, function ($constraint) { $constraint->aspectRatio(); $constraint->upsize(); }); // Save the new image $image->save($image_path, 100); // Load the image with Intervention Image $image = Image::make($image_path); // Resize the image while maintaining the aspect ratio $image->resize(600, 400, function ($constraint) { $constraint->aspectRatio(); $constraint->upsize(); }); // Save the thumbnail $image->save($thumb_path, 100); $data['image_path'] = $image_path; $data['thumb_path'] = $thumb_path; /* * If no errors save ALL the information to the * database table. */ if (empty($errors) === true) { // Save to Database Table CMS $timezone = new DateTimeZone('America/Detroit'); // Use your timezone here $today = new DateTime('now', $timezone); $data['date_updated'] = $data['date_added'] = $today->format("Y-m-d H:i:s"); $cms = new ImageContentManager($pdo, $data); $result = $cms->create(); if ($result) { header('Content-Type: application/json'); echo json_encode(['status' => 'success']); exit(); } } else { if (is_ajax_request()) { // Send a JSON response with errors for AJAX requests header('Content-Type: application/json'); echo json_encode(['status' => 'error', 'errors' => $errors]); } } } I log my errors to a log file that I can only see and a person needs to be login to my website even to upload a file. Maybe the above can you help you out a little. Just remember nothing is full proof, but you should make the code as tight as possible.
    1 point
  13. no matter how large you set the max_post_size setting, someone can upload a file that is larger. the size of the file someone tries to upload is out of your control. your code must test for this condition and handle it. also, by increasing the setting beyond a reasonable size, it will allow hackers to flood your server with huge uploaded files, consuming all the available processing and memory on the server, allowing a denial of service (DoS) attack.
    1 point
  14. The warning you are seeing tells you everything you need to know. Nothing to do with file type
    1 point
  15. Understand that this is a completely different problem than the one you asked for. Specifically, this is a great example of the X/Y problem: asking about your solution of "how to restrict window/tab sessions in PHP" as a means of accomplishing "we want to run some performance testing using multiple independent Chrome windows". Chrome is capable of running an instance (of the version installed on the computer) using a specific profile directory. It takes a little more setup since you need to create multiple profile directories, but that can be done mostly automatically with appropriate automation. If you're searching the internet for answers then look in the direction of automated UI testing: that universally involves scripting a browser to perform actions, which is what you want to do.
    1 point
  16. Firefox has an extension called Multi-Account Containers that allows you to basically sandbox each tab and prevent communication. Much like using private windows, but in tabs.
    1 point
  17. PHP can't tell the difference between one tab/window or another. The only option is to restrict all browsing such that the user never even leaves the page at all: by rewriting your site from the ground-up into a single-page application ("SPA"), meaning you're going to set aside a lot of PHP and do the majority of work in Javascript with frameworks like React. And by the way, this is a bad idea.
    1 point
This leaderboard is set to New York/GMT-04:00
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.