davidd07 Posted March 31, 2023 Share Posted March 31, 2023 (edited) I am using PHP TXT it seems to work well so far, however the username and password will run with a space, when entering two or more characters. For example: Create Account Username this will work with space need to one space Password ******** I have been trying to use preg_match with "/^[a-zA-Z0-9]*$/" but it just does not work on preg_match ($username) <?php $username = null; $password = null; $username_error = null; $password_error = null; $success = null; if(isset($_POST["sign-up"])) { $username = $_POST["username"]; $password = $_POST["password"]; if(empty(trim($username))) { if(preg_match("/^[a-zA-Z0-9]*$/", $username)) { $username = 0; $username_error = "<p><i>Username field has invalid content</i></p>"; } elseif(preg_match("/\\s/", $username)) { $username_error = "<p><i>Space found in username</i></p>"; } else { $username_error = "<p><i>Username field is empty</i></p>"; } } else { if(empty(trim($password))) { $password_error = "<p><i>Password field is empty</i></p>"; } else { $var = file("accounts.txt", FILE_SKIP_EMPTY_LINES|FILE_IGNORE_NEW_LINES); $exists = false; foreach($var as $key => $value) { $user = explode(' ', $value); if(trim($user[0]) == $username) { // we found a match this is enough to call it a duplicate $exists = true; break; } } if($exists) { $success = "<p class=\"success\">The username is already exists</p>"; } else { file_put_contents("accounts.txt", $username." ".$password.PHP_EOL, FILE_APPEND); $success = "<p class=\"success\">You are registered successfully</p>"; header("Location: login.php?status=success"); } } } } ?> <form method="POST" action="<?php echo $_SERVER["PHP_SELF"]; ?>"> <h4>Create Account</h4><br> <div> <label for="username">Username</label> <input type="text" name="username" value="<?php echo $_POST['username']; ?>"> <div class="error username-error"> <?php echo $username_error; ?> </div> </div> <div> <label>Password</label> <input type="password" name="password" value="<?php echo $_POST['password']; ?>"> <div class="error password-error"> <?php echo $password_error; ?> </div> </div> <p> <input type="submit" name="sign-up" value="Sign Up"> <div class="success"> <?php echo $success; ?> </div> </p> </form> Edited March 31, 2023 by davidd07 Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/ Share on other sites More sharing options...
kicken Posted March 31, 2023 Share Posted March 31, 2023 4 minutes ago, davidd07 said: if(empty(trim($username))) { if(preg_match("/^[a-zA-Z0-9]*$/", $username)) { $username = 0; $username_error = "<p><i>Username field has invalid content</i></p>"; } elseif(preg_match("/\\s/", $username)) { $username_error = "<p><i>Space found in username</i></p>"; } else { $username_error = "<p><i>Username field is empty</i></p>"; } } You are only checking the username for spaces/invalid characters if it's empty. If it's empty, then by definition it'll have no spaces or invalid characters. Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/#findComment-1606979 Share on other sites More sharing options...
davidd07 Posted March 31, 2023 Author Share Posted March 31, 2023 Sorry i cannot figure this out, is there some example of this? As I also tried if(strlen($username) - substr_count($username, ' ')) { $username_error = ".."; } Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/#findComment-1606980 Share on other sites More sharing options...
kicken Posted March 31, 2023 Share Posted March 31, 2023 (edited) Your code is simply not structured properly. Like I said above, you're only attempting to validating the username if it's empty. You should be doing the opposite, validating it if it's not empty. Even you made that change, the code would still fail because your code to save the results to the file would be in the else branch which would never run. What you need to do is re-structure the script to have your validation steps be independent and then check for overall success before saving the result. Something like: $errorList=[]; if (empty(trim($username))){ $errorList[]='Username is empty'; } else if (str_contains($username, ' ')){ $errorList[] = 'Username has a space'; } if (empty(trim($password))){ $errorList[] = 'Password is empty'; } if (count($errorList) === 0){ //No errors, do stuff } Edited March 31, 2023 by kicken Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/#findComment-1606982 Share on other sites More sharing options...
mac_gyver Posted March 31, 2023 Share Posted March 31, 2023 (edited) your code is not testing the same value for each field throughout the code, because you are trimming it in one place, but using the original value in other places. your post method form processing code should - not try to detect if the submit button isset(). instead, test if a post method form was submitted. don't create discrete variables for each form field and don't copy variables to other variables for nothing. instead, keep the form data as a set in a php array variable, then use elements in this array variable throughout the rest of the code. don't create separate variables for each error. instead, use an array for the user/validation errors. when you add errors to the array, use the field name as the array index. this will let you perform dependent validation tests on a field only when there are no previous validation errors and it will let you output the errors adjacent to the corresponding field if you desire. trim all the input data at once, then use the trimmed data throughout the rest of the code. after you do item #2 in this list, you can trim all the data using one single line of code. after the end of the validation logic, if there are no errors (the array holding the user/validation errors will be empty), use the form data. after the end of using the form data, if there are no errors, redirect to the exact same url of the current page to cause a get request for that page. to display a one-time success message, store it in a session variable, then test, display, and clear the session variable at the appropriate location in the html document. by passing the success message through the url in the redirect, you are opening your site to phishing attacks and cross site scripting. every redirect needs an exit/die statement to stop php code execution. a header() statement doesn't stop php code execution. if there are user/validation errors at step #5 or #6, the code will continue on to display the html document, display the errors, re-display the form, populating the field values with any existing data. any data you output in a html context should have htmlentities() applied to it to help prevent cross site scripting. Edited March 31, 2023 by mac_gyver Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/#findComment-1606983 Share on other sites More sharing options...
mac_gyver Posted April 1, 2023 Share Posted April 1, 2023 here's a list of suggestions for the code implementation - use a variable (or defined constant) for the file name so that if you need to change it, you can do so in a single location. if you were doing this for real, you would need to use file locking to insure that you don't corrupt/truncate the data file when there are multiple concurrent instances of your script trying to access the file. your code should test if the file exists before attempting to read it, in order to prevent php errors when the file initially doesn't exist. you should also test the result of the file() call in case the file does exist but it is empty. after you you read the data from the file, when you explode the data you should store it into an array, indexing it using the lowercase username. this will let you simply test if the lowercase submitted username exists in the data by using an isset() statement. by using the lowercase of the usernames from the data file and the lowercase of the submitted username, you will enforce uniqueness, e.g. MyUserName and myusername will be treated as the same value. the username that you store in the data file, and that you display, should retain the letter-case that was originally entered. to get a form to submit to the same page it is on, leave out the entire action='...' attribute. there's no need to use $_SERVER['PHP_SELF'] in this case and if you ever do need to use $_SERVER['PHP_SELF'], you need to apply htmlentities() to it to help prevent cross site scripting. if you put the closing </label> tag after the form field it goes with, you can leave out the for='...' and corresponding id='...' attributes (which you are currently missing most of.) Quote Link to comment https://forums.phpfreaks.com/topic/316074-when-registering-a-username/#findComment-1607000 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.