Empty fields error in PHP MySQLI signup form

Hello everyone! :slight_smile:

I have a code for a login system in php with mysqli here, but I keep getting the empty field error even though all fields are filled in. I’ve spent days with it, writing, correcting, overwriting, and rewriting the entire thing with no luck. The error message written below. The user is not added to the database.

What am I doing wrong? I’m fairly new to programming. All and any help is much appreciated! :slight_smile:

The error:
http:/localhost…/index.php?error=emptyfields&uid=User%20Name&[email protected]&date=2020-09-10&country=Denmark&tel=11111111

The code for signup system is here:

<?php

if (isset($_POST['signup-submit'])) {
require 'dbh.inc.php';

   $username = $_POST['uid'];
   $email = $_POST['mail'];
   $password = $_POST['pwd'];
   $passwordRepeat = $_POST['pwd-repeat'];
   $birthDate = $_POST['date'];
   $country = $_POST['country'];
   $telephone = $_POST['tel'];
 
   if (empty($username) || empty($email) || empty($password) || empty($passwordRepeat) || empty($birthDate) || empty($country) || empty($telephone)) {
     header("Location: ../index.php?error=emptyfields&uid=".$username."&mail=".$email."&date=".$birthDate."&country=".$country."&tel=".$telephone);
     exit();
   }
   elseif (!filter_var($email, FILTER_VALIDATE_EMAIL) && !preg_match("/^[a-zA_Z0-9]*$/", $username)){
     header("Location: ../index.php?error=invaliduidmail=");
     exit();
   }
   elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)){
     header("Location: ../index.php?error=invalidmail&uid=".$username);
     exit();
   }
   elseif (!preg_match("/^[a-zA_Z0-9]*$/", $username)){
     header("Location: ../index.php?error=invaliduid&mail=".$email);
     exit();
   }
   elseif ($password !== $passwordRepeat){
     header("Location: ../index.php?error=passwordcheck&mail=".$email."&uid=".$username);
     exit();
   }
   elseif (!preg_match("/^[a-zA_Z0-9]*$/", $birthDate)){
     header("Location: ../index.php?error=invaliddate&mail=".$email);
     exit();
   }
   elseif (!preg_match("/^[a-zA_Z]*$/", $country)){
     header("Location: ../index.php?error=invalidcountry&mail=".$email);
     exit();
   }
   elseif (!preg_match("/^[0-9]*$/", $telephone)){
     header("Location: ../index.php?error=invalidtel&mail=".$email);
     exit();
   }
   else {
     $sql = "SELECT emailUsers FROM users WHERE emailUsers=?";
     $stmt = mysqli_stmt_init($conn);
     if (!mysqli_stmt_prepare($stmt, $sql)) {
       header("Location: ../index.php?error=sqlerror");
       exit();
     }
     else {
       mysqli_stmt_bind_param($stmt, "s", $email);
       mysqli_stmt_execute($stmt);
       mysqli_stmt_store_result($stmt);
       $resultCheck = mysqli_stmt_num_rows($stmt);
       if ($resultCheck > 0) {
         header("Location: ../index.php?error=usertaken&uid=".$username);
         exit();
       }
       else{
         $sql = "INSERT INTO users (uidUsers, emailUsers, pwdUsers, birthUsers, countryUsers, telUsers) VALUES (?, ?, ?, ?, ?, ?)";
         $stmt = mysqli_stmt_init($conn);
         if (!mysqli_stmt_prepare($stmt, $sql)) {
           header("Location: ../index.php?error=sqlerror");
           exit();
         }
         else {
           $hashedpwd = password_hash($password, PASSWORD_DEFAULT);
 
           mysqli_stmt_bind_param($stmt, "ssssss", $username, $email, $hashedpwd, $birthDate, $country, $telephone);
           mysqli_stmt_execute($stmt);
           header("Location: ../index.php?signup=success");
           exit();
         }
       }
     }
   }
   mysqli_stmt_close($stmt);
   mysqli_close($conn);
 
 }
 else{
   header("Location: ../index.php");
   exit();
 }

The code for the signup form is here:

        <form class="frm" action="includes/signup.inc.php" method=post>
          <input type="text" name="uid" placeholder="Name">
          <input type="text" name="mail" placeholder="E-mail address">
          <input type="password" id="pwd" placeholder="Password">
          <input type="password" id="pwd-repeat" placeholder="Repeat password">
          <input type="date" name="date" placeholder="dd/mm/yyyy">
          <input type="text" name="country" placeholder="Country">
          <input type="tel" name="tel" placeholder="Telephone number">
          <button class="btn2" type"submit" name="signup-submit">Join us</button>
        </form>

I/We have seen this unnecessarily complex coding pattern too much lately. Wherever you learned this coding pattern at, forget you ever saw it. You have a wall of implementation code that’s hiding mistakes and providing a bad User eXperience (UX).

Your code should -

  1. Have the form and form processing code on the same page. This will let you easily produce and display unique and helpful user error messages for each problem with the submitted form data. It will simplify the code since it will eliminate all the redirects and the needed logic in the form, which I don’t think you have written yet, to produce and display actual error messages based on the cryptic values in the url. You can also re-populate the form field values when you re-display the form when there are validation errors, so that the user doesn’t need to keep reentering the same data over and over.
  2. Don’t try to test if the submit button is set. There are cases where it won’t be. Instead, test if a post method form has been summitted.
  3. Don’t copy variables to other variables without any reason. This is just a waste of typing. Keep the submitted form data as an array and operate on elements in the array throughout the rest of the code.
  4. Don’t change the name of something from one point to the next. Use the same name for any one piece of data throughout the code.
  5. Trim all input data before validating it, so that you can detect if all white-space characters were entered. You can do this using one single line of code.
  6. Perform all independent validation tests separately, storing validation error messages in an array, using the field name as the array index. The only time you should have elseif/else validation logic is when performing dependent validation tests, that depend on the result of previous test(s). This errors array is also an error flag. If the array is empty, there are no errors and you can use the submitted form data. You can test/display the content of this array at the appropriate point in the html document.
  7. Don’t lump validation tests together in one statement and don’t build all possible combination of tests.
  8. Don’t try to SELECT data in order to decide if it already exists. There’s a race/timing condition with multiple concurrent instances of your script all finding that the value doesn’t exist and will try to insert it, either producing a duplicate error or resulting in duplicate values in your database. Instead, define the column(s) in your database table as a unique index, just attempt to insert the data, then detect if the query produced a duplicate index error number.
  9. Don’t use multiple statements when something can be accomplished using a single statement. This combination of mysqli_stmt_init/mysqli_stmt_prepare started showing up in help questions recently. Just use mysqli_prepare().
  10. Don’t tell the user that a database error has occurred unless he/she can do something about the error, such as when inserting/updating duplicate data values. In all other cases, the user cannot do anything about a database statement error and letting a hacker know that something they did caused an error will just encourage them to do more of the same. Also, don’t unconditionally output the raw database errors onto a web page. Instead, use exceptions for database statement errors and in most cases let php catch and handle the exception where php will use its error related settings to control what happens with the actual error information (database statement errors will ‘automatically’ get displayed/logged the same as php errors.) This will let you eliminate all the existing database statement error handling logic, since it will no longer get executed upon an error.
  11. Switch to the much simpler PDO database extension. About half of the database statements will go away.
  12. In most cases, there’s no need to close prepared statements or close the database connection as all resources used on a page will be destroyed by php when the script ends.
  13. The only redirect your form processing code should have is redirect to the exact same url of the page upon successfully completing the form processing code. If you want to display a one-time success message, store it in a session variable, then test, display, and clear that session variable at the appropriate point in the html document.
  14. Any dynamic value you output on a web page should have htmlentities() applied to it to help prevent cross site scripting.
  15. As an advanced programming topic, when you have more than 2-3 form fields, you should dynamically validate and process them, using a data-driven design.

Most of these points will actually simplify the code, so that you can concentrate on what the code is trying to do, rather than on the implementation details.

Lastly, for debugging problems with submitted form data, add the following line of code before the start of your form processing so that you can see what the form data actually is -

echo '<pre>'; print_r($_POST); echo '</pre>';
1 Like

Hi phdr!

Thank you very much for your very constructive and comprehensive answer!

As I mentioned, I’m new to programming. Do you by any chance know a couple of good resources where I can learn “good” php coding? Obviously, I shouldn’t continue with the one, I’m currently learning from. :slight_smile:

Unfortunately, most of the code examples posted on the web are just barely good enough to ‘work’ under ideal conditions, are out of date, insecure, don’t provide a good UX, are filled with unnecessary make-work things that don’t add any value, don’t have any logic that would get them to tell (display/log) why they don’t work, and were posted more for search engine ranking/advertisement income, than to actually be helpful. You can find useful elements in the information posted on the web but that’s how you should treat it, by looking at what and how something is being done, not just reproducing it, and determining for yourself which if anything has value that you want to make use of.

Learning the php language elements is best done by using the php.net documentation. It is basically the dictionary for the php language. However, the examples in the php.net documentation show how you can do something, not necessarily how you should do something in an actual application. Learning how to program involves experimenting, learning, and building upon each fundamental skill, until you learn enough so that you can decide for yourself which statements to use and how to put those statements together so that they do something useful. Learning what each individual element actually does also allows you to find problems in your code, yourself, because you will know what should be occurring as the result of each statement. When someone posts code in a help forum, I/we read it, starting with line number one, adding up what each statement contributes to the ‘story’ being written. When we get to the end, if everything used the correct syntax and made logical sense, we know what the programmer/author was trying to accomplish.

If you are just starting out, start small. Create a form and form processing code to insert just one form field, such as the username (and don’t refer to it as uid, username, uidUsers, and name at different points in the process.) Once you get all the logic to work correctly for that one field, for correct, incorrect, and previously stored input values, you can worry about what’s needed for all the rest of the fields.

As far as my list of programming practices given above, work on one item at a time, researching and asking questions as needed.

2 Likes

I just like to add having good knowledge of HTML/CSS with a little Javascript (I suggest Vanilla Javascript) will aid in learning a server side language such as PHP. That way a new user can (I think should) do a static mockup what they are trying to do and then add the dynamic element using PHP (or another server based language). I know things started to click when I started doing small mockups and made me to understand PHP better. I’m still learning new programming techniques in PHP either by reading up on it or being pointed out mistakes on a forum by a more experienced PHP coder. Not having to deal with trying to learn HTML/CSS at the same time also saves on a few headaches. I think the best and sometimes hardest way to learn is by making mistakes. Initially it is a bit of a bummer, but the key thing is to learn from those mistakes and to hopefully to avoid them in the future. Don’t be hesitant to post a problem with a script that you are having and don’t get upset or angry at the person trying help if the person is just being truthful with his or her answer. You would rather learn the truth on what you are doing wrong than to have someone sugarcoat the problem or don’t point out that that you are on the wrong path when it comes to coding. I have seen many times people try to sugarcoat their response as they don’t want to be seen as the “bad” guy. I just like to add that people try to give you the best possible fix to your problem, but they are human as well and sometimes their fix is wrong. That is why you should read all the replies that you get. I know in the past I have given a fix that was wrong or there was an easier way of doing it. It wasn’t intentional on my part and when I see that I was wrong with the answer then I just put that in my database for future replies that I make and go back to my own code to fix it. LOL :laughing:
I think the hardest error to debug is the logic error as that can be frustrating as all can be. It doesn’t spit out an error message like a syntax error does as it can be almost anywhere in the code or even how you have your local server setup (those really annoy me). That’s why it’s important to have error reporting turn on when developing PHP scripts NOT on a production server, so you can spot the difference between a syntax error and a logic error. It’s usually a great relief when it’s a syntax error although a few syntax errors can be tricky at times. I know it took me a long time to understand the correct syntax for namespaces in Classes. I create a library of procedural functions (later on when you get most accustomed to PHP - Library of Classes) that way you can reuse the over again in the next project, it’s a nice way to understand PHP seeing it broke down in smaller chunks of code and you don’t have to use a framework (unless you were working with one in the first place).

1 Like

Thanks a million again for your response! I have downloaded a book on php (PHP & MySQL: Novice to Ninja, 6ed.), and checked out php.net, which I’ll start with. I’ll start small, as you say, and progress to more complex things. The language isn’t as straight forward as HTML og CSS. I thought I could just jump into it, and learn by adjusting the code to my needs, and fixing mistakes as they come. Apparently, it’s not as simple as that. :smile: Even though it worked for HTML and CSS.

Thanks a lot for your response, and tips! I absolutely agree with you. That’s the way to learn things. I’m open to all criticism, tips, and tricks a more experienced programmer can give me. After all, I’m interested in learning the language to produce good quality secure code.

I think I have an ok understanding of HTML/CSS, I think. :see_no_evil: I’ll have to learn some Javascript though.

I’m glad that I got the response I got, and not had a, let’s say, “suboptimal” piece of code fixed for me. That’s a learning process. :blush:

I think an idea with creating own library is very good. :+1:

Sponsor our Newsletter | Privacy Policy | Terms of Service