Last modified on August 20th, 2019 by Vincy.

User login and registration is a basic requirement for any CMS applications. This is the initial work while starting a project. Application with user login authentication provides security by preventing anonymous access. There are various ways to enable authentication in our application like by enabling OAuth login or by implementing Single Sign-on (SSO) and similar other ways. In a previous tutorial, we have seen how to implement and also about .

This example includes both login and the registration functionalities. I have used MySQL database to store the registered members. The user registration will contain input to get the details from the user. On submitting this form, the form data are posted to PHP and stored in the database. User password will be encrypted before storing into the database. before posting to the PHP code. When the user is logged in with the valid credentials, then the user and he will be allowed to proceed further.

User Registration Form

This code is to show the signup form to the user. When the user submits the form with his details, the JavaScript function will be called to validate user input. After successful validation, the PHP code will read the posted form data to execute database insert.

">

The JavaScript validation will take care of the mandatory fields’ non-empty check and also email format validation with regex pattern.

This PHP code to create insert using the registration form data. After executing the database insert the success/error response will be sent to acknowledge the user.

openConnection(); $sql1 = "select name, email from tbl_registered_users where email="$email""; $user = $db->query($sql1); $result = $user->fetchAll(); $_SESSION["emailname"] = $result["email"]; if (empty($result)) ( $sql = "insert into tbl_registered_users (name,email, password) values("$name","$email","$password")"; $db->exec($sql ); $database->closeConnection(); $response = array("type" => "success", "message" => "You have registered successfully.
Now Login."); ) else ( $response = array("type" => "error", "message" => "Email already in use."); ) ) ?>

Login Authentication using PHP

The registered user can login to the application via this login form. The login authentication is done by matching the login email and password with the registered user database. If match found then the application will allow the user to proceed further. Otherwise, the login panel will acknowledge the user about the invalid attempt.

The PHP code for validating the user login with the database is shown below. After successful login, I redirect the user to the dashboard.php. The dashboard will show the welcome message by addressing the logged-in member. Also, there will be an option to log out the current session.

openConnection(); $sql = "select * from tbl_registered_users where email = "$email" and password= "$password""; $user = $db->query($sql); $result = $user->fetchAll(PDO::FETCH_ASSOC); $id = $result["id"]; $name = $result["name"]; $email = $result["email"]; $_SESSION["name"] = $name; $_SESSION["id"] = $id; $database->closeConnection(); header("location: dashboard.php"); ) ?>

In this article, you will learn how to create a registration and authorization form using HTML, JavaScript, PHP and MySql. Such forms are used on almost every site, regardless of its type. They are created for the forum, and for the online store and for social networks (such as Facebook, Twiter, Odnoklassniki) and for many other types of sites.

If you have a site on your local computer, then I hope you already have . Nothing will work without it.

Creating a Table in the Database

In order to implement user registration, we first need a Database. If you already have it, then great, otherwise, you need to create it. In the article, I explain in detail how to do this.

And so, we have a Database (abbreviated DB), now we need to create a table users in which we will add our registered users.

How to create a table in the database, I also explained in the article. Before creating a table, we need to define what fields it will contain. These fields will match the fields from the registration form.

So, we thought, imagined what fields our form will have and create a table users with these fields:

  • id- Identifier. Field id should be in every table from the database.
  • first_name- To save the name.
  • last_name- To save the last name.
  • email- To save the postal address. We will use e-mail as a login, so this field must be unique, that is, have a UNIQUE index.
  • email_status- A field to indicate whether the mail is confirmed or not. If the mail is confirmed, then it will have a value of 1, otherwise the value of 0.
  • password- To save the password.


If you want your registration form to have some more fields, you can add them here as well.

That's it, our table users ready. Let's move on to the next step.

Database connection

We have created the database, now we need to connect to it. We will connect using the MySQLi PHP extension.

In the folder of our site, create a file with the name dbconnect.php, and in it we write the following script:

Database connection error. Error Description: ".mysqli_connect_error()."

"; exit(); ) // Set the connection encoding $mysqli->set_charset("utf8"); //For convenience, add a variable here that will contain the name of our site $address_site = "http://testsite.local" ; ?>

This file dbconnect.php will need to be connected to form handlers.

Pay attention to the variable $address_site, here I have indicated the name of my test site, which I will work on. You accordingly indicate the name of your site.

Site structure

Now let's take a look at the HTML structure of our site.

Move the site header and footer to separate files, header.php and footer.php. We will connect them on all pages. Namely, on the main (file index.php), to the page with the registration form (file form_register.php) and on the page with the authorization form (file form_auth.php).

Block with our links, registration and authorization, add to the header of the site so that they are displayed on all pages. One link will enter on registration form page(file form_register.php) and the other to the page with authorization form(file form_auth.php).

Content of header.php file:

The name of our site

As a result, our main page looks like this:


Of course, your site may have a completely different structure, but this is not important for us now. The main thing is that there are links (buttons) for registration and authorization.

Now let's move on to the registration form. As you already understood, we have it in the file form_register.php.

We go to the Database (in phpMyAdmin), open the table structure users and see what fields we need. So, we need fields for entering a first and last name, a field for entering a postal address (Email) and a field for entering a password. And for security purposes, we will add a captcha input field.

On the server, as a result of processing the registration form, various errors may occur due to which the user will not be able to register. Therefore, in order for the user to understand why the registration fails, it is necessary to display messages about these errors to him.

Before displaying the form, we add a block to display error messages from the session.

And another moment, if the user is already authorized, and for the sake of interest, he enters the registration page directly by writing in the address bar of the browser website_url/form_register.php, then in this case, instead of the registration form, we will display a title for it that it is already registered.

In general, the file code form_register.php we got it like this:

You are already registered

In the browser, the registration page looks like this:


Via required attribute, we have made all fields mandatory.

Pay attention to the registration form code where captcha is displayed:


We in the value of the src attribute for the image, specified the path to the file captcha.php, which generates this captcha.

Let's look at the code of the file captcha.php:

The code is well commented, so I'll just focus on one point.

Inside a function imageTtfText(), the path to the font is specified verdana.ttf. So for the captcha to work correctly, we must create a folder fonts, and put the font file there verdana.ttf. You can find and download it from the Internet, or take it from the archive with the materials of this article.

We are done with the HTML structure, it's time to move on.

Validating email with jQuery

Any form needs validation of the entered data, both on the client side (using JavaScript, jQuery) and on the server side.

We must pay special attention to the Email field. It is very important that the entered email address is valid.

For this input field, we set the type email (type="email"), this warns us a little bit against incorrect formats. But, this is not enough, because through the code inspector that the browser provides us, you can easily change the value of the attribute type with email on text, and that's it, our check will no longer be valid.


And in that case, we have to make a more reliable check. To do this, we will use the jQuery library from JavaScript.

To connect the jQuery library, in the file header.php between tags , before the closing tag , add this line:

Right after this line, add the email validation check code. Here we add the code for checking the length of the entered password. It must be at least 6 characters long.

With the help of this script, we check the entered email address for validity. If the user entered the wrong Email, then we display an error about it and deactivate the submit button of the form. If everything is fine, then we remove the error and activate the submit button of the form.

And so, with the form validation on the client side, we are done. Now we can send it to the server, where we will also do a couple of checks and add data to the database.

User registration

We send the form for processing to the file register.php, via the POST method. The name of this handler file, specified in the attribute value action. And the send method is specified in the attribute value method.

Open this file register.php and the first thing we need to do is write a session launch function and include the file we created earlier dbconnect.php(In this file, we made a connection to the database). And yet, immediately declare the cells error_messages and success_messages in the session global array. AT error_mesages we will record all error messages that occur during form processing, and in success_messages Let's write happy messages.

Before continuing, we must check whether the form was submitted at all. An attacker can look at the value of an attribute action from the form, and find out which file is processing this form. And he may come up with the idea to go directly to this file by typing the following address in the address bar of the browser: http://site_site/register.php

So we need to check if there is a cell in the global POST array whose name matches the name of our "Register" button from the form. Thus, we check whether the "Register" button was pressed or not.

If an attacker tries to go directly to this file, he will receive an error message. I remind you that the $address_site variable contains the name of the site and it was declared in the file dbconnect.php.

Mistake! main page .

"); } ?>

The captcha value in the session was added during its generation, in the file captcha.php. As a reminder, I will show once again this piece of code from the file captcha.php, where the captcha value is added to the session:

Now let's get to the test itself. In file register.php, inside the if block, where we check whether the "Register" button was pressed, or rather, where the comment " // (1) Place for the next piece of code"we write:

//Check the received captcha //Trim spaces from the beginning and from the end of the string $captcha = trim($_POST["captcha"]); if(isset($_POST["captcha"]) && !empty($captcha))( //Compare the received value with the value from the session. if(($_SESSION["rand"] != $captcha) && ($_SESSION ["rand"] != ""))( // If the captcha is not correct, then return the user to the registration page, and there we will display an error message that he entered the wrong captcha. $error_message = "

Mistake! You entered the wrong captcha

"; // Save the error message to the session. $_SESSION["error_messages"] = $error_message; // Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site ."/form_register.php"); //Stop the script exit(); ) // (2) Place for the next piece of code )else( //If the captcha is not passed or it is empty exit("

Mistake! There is no verification code, that is, the captcha code. You can go to the main page.

"); }

Next, we need to process the received data from the POST array. First of all, we need to check the contents of the global POST array, that is, whether there are cells there whose names match the names of the input fields from our form.

If the cell exists, then we trim the spaces from the beginning and from the end of the string from this cell, otherwise, we redirect the user back to the page with the registration form.

Further, after the spaces have been trimmed, we add a string to the variable and check this variable for emptiness, if it is not empty, then move on, otherwise we redirect the user back to the page with the registration form.

Paste this code in the specified location // (2) Place for the next piece of code".

/* Check if the global array $_POST contains data submitted from the form and enclose the submitted data in regular variables.*/ if(isset($_POST["first_name"]))( // Trim spaces from the beginning and end of the string $first_name = trim($_POST["first_name"]); //Check if the variable is empty if(!empty($first_name))( // For safety, convert special characters to HTML entities $first_name = htmlspecialchars($first_name, ENT_QUOTES) ; )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Enter your name

Name field missing

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) if( isset($_POST["last_name"]))( // Trim spaces from the beginning and end of the string $last_name = trim($_POST["last_name"]); if(!empty($last_name))( // For safety , convert special characters to HTML entities $last_name = htmlspecialchars($last_name, ENT_QUOTES); )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Enter your last name

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

Name field missing

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) if( isset($_POST["email"]))( // Trim spaces from the beginning and end of the string $email = trim($_POST["email"]); if(!empty($email))( $email = htmlspecialchars ($email, ENT_QUOTES); // (3) Place of code to check the format of the email address and its uniqueness )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Enter your email

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) if( isset($_POST["password"]))( // Trim spaces from the beginning and end of the string $password = trim($_POST["password"]); if(!empty($password))( $password = htmlspecialchars ($password, ENT_QUOTES); //Encrypt the password $password = md5($password."top_secret"); )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Enter your password

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) // (4) Place for the code for adding a user to the database

The field is of particular importance. email. We have to check the format of the received mailing address and its uniqueness in the database. That is, whether a user with the same email address is already registered.

At the specified location" // (3) Place of code to check the format of the postal address and its uniqueness" add the following code:

//Check the format of the received email address using the regular expression $reg_email = "/^**@(+(*+)*\.)++/i"; //If the format of the received email address does not match the regular expression if(!preg_match($reg_email, $email))( // Save the error message to the session. $_SESSION["error_messages"] .= "

You entered an invalid email

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) // Check if there is already such an address in the database $result_query = $mysqli->query("SELECT `email` FROM `users` WHERE `email`="".$email."""); If there are exactly one rows, then the user with this email address is already registered if($result_query->num_rows == 1)( //If the result is not false if(($row = $result_query->fetch_assoc()) != false) ( // Save the error message to the session. $_SESSION["error_messages"] .= "

User with this email address is already registered

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); )else( //Save the error message to the session .$_SESSION["error_messages"] .= "

Error in database query

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); ) /* close the selection */ $result_query-> close(); //Stop the script exit(); ) /* close the selection */ $result_query->close();

And so, we are done with all the checks, it's time to add the user to the database. At the specified location" // (4) Place for the code for adding a user to the database" add the following code:

//Query to add a user to the database $result_query_insert = $mysqli->query("INSERT INTO `users` (first_name, last_name, email, password) VALUES ("".$first_name."", "".$last_name." ", "".$email."", "".$password."")"); if(!$result_query_insert)( // Save the error message to the session. $_SESSION["error_messages"] .= "

Error request to add a user to the database

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); )else( $_SESSION["success_messages"] = "

Registration completed successfully!!!
Now you can log in using your username and password.

"; //Send the user to the login page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); ) /* Complete the request */ $result_query_insert-> close(); //Close the database connection $mysqli->close();

If an error occurs in the request to add a user to the database, we add a message about this error to the session and return the user to the registration page.

Otherwise, if everything went well, we also add a message to the session, but it is already more pleasant, namely, we tell the user that the registration was successful. And we redirect it to the page with the authorization form.

The script for checking the format of the email address and the length of the password is in the file header.php, so it will affect fields from that form as well.

The session is also started in the file header.php, so in the file form_auth.php the session does not need to be started, because we get an error.


As I said, the script for checking the format of the mail address and the length of the password also works here. Therefore, if the user enters the wrong email address or short password, he will immediately receive an error message. A button to come in will become inactive.

After fixing the errors, the button to come in becomes active and the user can submit the form to the server where it will be processed.

User authorization

To attribute value action the authorization form has a file auth.php, which means that the form will be processed in this file.

So let's open the file auth.php and write the code to process the authorization form. The first thing to do is start the session and include the file dbconnect.php to connect to the database.

//Declare a cell to add errors that may occur during form processing. $_SESSION["error_messages"] = ""; //Declare a cell to add successful messages $_SESSION["success_messages"] = "";

/* Check if the form was submitted, that is, if the Login button was clicked. If yes, then we go further, if not, then we will display an error message to the user, stating that he went to this page directly. */ if(isset($_POST["btn_submit_auth"]) && !empty($_POST["btn_submit_auth"]))( //(1) Place for the next piece of code )else( exit("

Mistake! You have accessed this page directly, so there is no data to process. You can go to the main page.

"); }

//Check the received captcha if(isset($_POST["captcha"]))( //Trim spaces from the beginning and end of the string $captcha = trim($_POST["captcha"]); if(!empty($captcha ))( //Compare the received value with the value from the session. if(($_SESSION["rand"] != $captcha) && ($_SESSION["rand"] != ""))( // If the captcha is invalid , then we return the user to the authorization page, and there we will display an error message that he entered the wrong captcha. $error_message = "

Mistake! You entered the wrong captcha

"; // Save the error message to the session. $_SESSION["error_messages"] = $error_message; // Return the user to the authorization page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site ."/form_auth.php"); //Stop the script exit(); ) )else( $error_message = "

Mistake! The captcha input field must not be empty.

"; // Save the error message to the session. $_SESSION["error_messages"] = $error_message; // Return the user to the authorization page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site ."/form_auth.php"); //Stop the script exit(); ) //(2) Place for processing the mail address //(3) Place for processing the password //(4) Place for making a query to the database )else ( //If captcha is not passed exit("

Mistake! There is no verification code, that is, the captcha code. You can go to the main page.

"); }

If the user has entered the verification code correctly, then we move on, otherwise we return him to the authorization page.

Email address verification

// Trim spaces from the beginning and end of the string $email = trim($_POST["email"]); if(isset($_POST["email"]))( if(!empty($email))( $email = htmlspecialchars($email, ENT_QUOTES); //Check the format of the received email address using the regular expression $reg_email = " /^**@(+(*+)*\.)++/i"; //If the format of the received email address does not match the regular expression if(!preg_match($reg_email, $email))( // Save to the session error message.$_SESSION["error_messages"] .= "

You entered an invalid email

"; //Return the user to the authorization page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

The field for entering the postal address (email) should not be empty.

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_register.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

There is no field for entering Email

"; //Return the user to the authorization page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); ) // (3) Place for password processing

If the user has entered an email address in the wrong format or the value of the email address field is empty, then we return him to the authorization page, where we display a message about this.

Password check

The next field to process is the password field. To the designated place" //(3) Place for password processing", we write:

If(isset($_POST["password"]))( // Trim spaces from the beginning and end of the string $password = trim($_POST["password"]); if(!empty($password))( $password = htmlspecialchars($password, ENT_QUOTES); // Encrypt the password $password = md5($password."top_secret"); )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Enter your password

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); ) )else ( // Save the error message to the session. $_SESSION["error_messages"] .= "

There is no field for entering a password

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); )

Here, using the md5 () function, we encrypt the received password, since in the database we have passwords in encrypted form. Additional secret word in encryption, in our case " top_secret" must be the one that was used when registering the user.

Now you need to make a query to the database on a user selection whose mail address is equal to the received mail address and the password is equal to the received password.

//Query to the database on the user's selection. $result_query_select = $mysqli->query("SELECT * FROM `users` WHERE email = "".$email."" AND password = "".$password."""); if(!$result_query_select)( // Save the error message to the session. $_SESSION["error_messages"] .= "

Query error on user selection from database

"; //Return the user to the registration page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); )else( //Check if there is no user with such data in the database, then display an error message if($result_query_select->num_rows == 1)( // If the entered data matches the data from the database, then save the login and password to the session array. $_SESSION["email"] = $email; $_SESSION["password"] = $password; //Return the user to the main page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site ."/index.php"); )else( // Save the error message to the session. $_SESSION["error_messages"] .= "

Wrong username and/or password

"; //Return the user to the authorization page header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$address_site."/form_auth.php"); //Stop the script exit(); ) )

Site exit

And the last thing we implement is exit procedure. At the moment, in the header we display links to the authorization page and the registration page.

In the site header (file header.php), using the session, we check if the user is already logged in. If not, then we display the registration and authorization links, otherwise (if it is authorized), then instead of the registration and authorization links we display the link Exit.

Modified piece of code from file header.php:

Registration

Exit

When you click on the exit link from the site, we get into the file logout.php, where we simply destroy the cells with the email address and password from the session. After that, we return the user back to the page on which the link was clicked exit.

File code logout.php:

That's all. Now you know how implement and process registration and authorization forms user on your site. These forms are found on almost every site, so every programmer should know how to create them.

We also learned how to validate input data, both on the client side (in the browser, using JavaScript, jQuery) and on the server side (using the PHP language). We also learned implement logout procedure.

All scripts are tested and working. You can download the archive with the files of this small site from this link.

In the future I will write an article where I will describe. And I also plan to write an article where I will explain (without reloading the page). So, in order to be aware of the release of new articles, you can subscribe to my site.

If you have any questions, please contact, also, if you notice any mistake in the article, please let me know.

Lesson Plan (Part 5):

  1. Creating an HTML Structure for the Authorization Form
  2. We process the received data
  3. We display the user's greeting in the header of the site

Liked the article?

Reg.ru: domains and hosting

The largest registrar and hosting provider in Russia.

Over 2 million domain names in service.

Promotion, mail for domain, solutions for business.

More than 700 thousand customers around the world have already made their choice.

*Mouseover to pause scrolling.

Back forward

Creating a simple user registration system in PHP and MySQL

Creating a registration system is a lot of work. You have to write code that validates email addresses, sends a registration confirmation email, validates the rest of the form fields, and much more.

And even after you write all this, users will be reluctant to register, because. it requires some effort on their part.

In this tutorial, we'll create a very simple login system that doesn't require or store passwords at all! The result will be easy to modify and add to an already existing PHP site. Want to find out how it works? Read below.



Here's how our super simple system would work:

We will combine the authorization form and registration. This form will have a field for entering an email address and a registration button;
- When filling in the field with an email address, by clicking on the register button, a record about a new user will be created, but only if the entered email address was not found in the database.

After that, a certain random unique set of characters (token) is created, which is sent to the mail specified by the user in the form of a link that will be relevant for 10 minutes;
- By clicking on the link, the user goes to our website. The system determines the presence of the token and authorizes the user;

The advantages of this approach:

No need to store passwords and validate fields;
- No need for password recovery, secret questions, etc.;
- From the moment a user has registered/logged in, you can always be sure that this user will be in your access zone (that the email address is true);
- Incredibly simple registration process;

Flaws:

User account security. If someone has access to the user's mail, he can log in.
- Email is not secure and can be intercepted. Keep in mind that this question is also relevant in the case when the password has been forgotten and needs to be restored, or in any authorization system that does not use HTTPS for data transfer (login / password);
- As long as you set up the mail server as needed, there is a chance that messages with authorization links will end up in spam;

Comparing the advantages and disadvantages of our system, we can say that the system has high usability (maximum convenience for the end user) and, at the same time, has a low security indicator.

So it is proposed to use it for registrations on forums and services that do not work with important information.

How to use this system

In the case when you just need to use the system to authorize users on your site, and you do not want to take this lesson apart, here's what you need to do:

You need to download the source files attached to the lesson
- Find the file in the archive tables.sql Import it into your database using the import option in phpMyAdmin. Alternative way: open this file with a text editor, copy the SQL query and run it;
- Open includes/main.php and fill in the settings for connecting to your database (specify the user and password for connecting to the database, as well as the host and name of the database). In the same file, you must also specify an email address that will be used as the original address for messages sent by the system. Some hosts will block outgoing emails until the form shows a real email address that was generated from the host's control panel, so enter the real address;
- Download all files index.php, protected.php and the assets and includes folders via FTP to your host;
- Add the code below to each PHP page where you want to display an authorization form;

Require_once "includes/main.php"; $user = new User(); if(!$user->loggedIn())( redirect("index.php"); )
- Ready!

For those who are interested in how it all works, read on below!

The first step is writing the HTM code for the authorization form. This code is located in the file index.php. This file also contains the PHP code that handles the form data and other useful features of the authorization system. You can learn more about this in the PHP code review section below.

index.php

Tutorial: Super Simple Registration System With PHP & MySQL

Login or Register

Enter your email address above and we will send
you login link.

In the head section (between tags and) I included the main styles (they are not analyzed in this tutorial, so you can see them yourself. The assets/css/style.css folder). Before the closing tag I included the jQuery library and the script.js file, which we will write and analyze below.


JavaScript

jQuery keeps track of the state of the "Sign Up/Login" button with a function e.preventDefault() and sends AJAX requests. Depending on the server's response, displays a particular message and determines further actions /

assets/js/script.js

$(function()( var form = $("#login-register"); form.on("submit", function(e)( if(form.is(".loading, .loggedIn"))( return false ; ) var email = form.find("input").val(), messageHolder = form.find("span"); e.preventDefault(); $.post(this.action, (email: email), function (m)( if(m.error)( form.addClass("error"); messageHolder.text(m.message); ) else( form.removeClass("error").addClass("loggedIn"); messageHolder. text(m.message); ) )); )); $(document).ajaxStart(function()( form.addClass("loading"); )); $(document).ajaxComplete(function()( form. removeClass("loading"); )); ));

was added to the form to display the current state of the AJAX request (this was made possible thanks to the methods ajaxStart()) and ajaxComplete(), which you can find towards the end of the file).

This class shows a spinning animated gif file (as if hinting to us that the request is being processed), and also acts as a flag to prevent the form from being resubmitted (when the register button has already been clicked once). Class .loggedIn- this is a different flag - set when the email was sent. This flag instantly blocks any further action on the form.

Database Schema

Our incredibly simple logging system uses 2 MySQL tables (the SQL code is in the file tables.sql). The first stores data about user accounts. The second stores information about the number of login attempts.


User table schema.

The system does not use passwords, which can be seen in the diagram. On it you can see the column token with tokens adjacent to the column token_validity. The token is set as soon as the user connects to the system, sets his email to send a message (a little more about this in the next block). Speaker token_validity sets the time 10 minutes later, after which the token is no longer valid.


Table schema that counts the number of authorization attempts.

In both tables, the IP address is stored in a processed form, using the ip2long function, in an integer field.

Now we can write some PHP code. The main functionality of the system is assigned to the class user.class.php which you can see below.

This class actively uses idorm (docs), these libraries are the minimum necessary tools for working with databases. It handles database access, token generation and validation. It is a simple interface that makes it easy to connect a registration system to your site if it uses PHP.

user.class.php

Class User( // Private ORM case private $orm; /** * Find a user by token. Only valid tokens are taken into consideration. The token is generated only for 10 minutes from the moment it was created * @param string $token. This is the one you are looking for token * @return User. Return the value of the User function */ public static function findByToken($token)( // find the token in the database and make sure the correct timestamp is set $result = ORM::for_table("reg_users") ->where ("token", $token) ->where_raw("token_validity > NOW()") ->find_one(); if(!$result)( return false; ) return new User($result); ) /** * Authorize or register a user * @param string $email.User's email address * @return User */ public static function loginOrRegister($email)( // If such a user already exists, return the value of the User function from the specified email address stored in the database if(User::exists($email))( return new User($email); ) // Otherwise, create a new user tel in the database and return the value of the User::create function from the specified email return User::create($email); ) /** * Create a new user and save to the database * @param string $email. User email address * @return User */ private static function create($email)( // Register a new user and return the result of the User function from these values ​​$result = ORM::for_table("reg_users")->create(); $result->email = $email; $result->save(); return new User($result); ) /** * Check if such a user exists in the database and return the boolean value of variable * @param string $email. User email address * @return boolean */ public static function exists($email)( // Does the user exist in the database? $result = ORM::for_table("reg_users") ->where("email", $email) ->count(); return $result == 1; ) /** * Create a new user object * @param instance $param ORM , id, email or 0 * @return User */ public function __construct($param = null) ( if($param instanceof ORM)( // ORM check passed $this->orm = $param; ) else if(is_string($param))( // Email check passed $this->orm = ORM::for_table ("reg_users") ->where("email", $param) ->find_one(); ) else( $id = 0; if(is_numeric($param))( // user id is passed the value of $param variable $id = $param; ) else if(isset($_SESSION["loginid"]))( // Otherwise see session $id = $_SESSION["loginid"]; ) $this->orm = ORM::for_table( "reg_users") ->where("id", $id) ->find_one(); ) ) /** * Generate a new SHA1 authorization token, writes to the database and returns its value * @return string */ public function generateToken()( // Generate a token for an authorized user and save it to the database $token = sha1($this->email.time().rand(0, 1000000 )); // Store the token in the database // And mark it as only valid for the next 10 minutes $this->orm->set("token", $token); $this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")"); $this->orm->save(); return $token; ) /** * Authorize the user * @return void */ public function login()( // Mark the user as logged in $_SESSION["loginid"] = $this->orm->id; // Update the value of the last_login database field $this->orm->set_expr("last_login", "NOW()"); $this->orm->save(); ) /** * Destroy the session and log out the user * @return void */ public function logout ()( $_SESSION = array(); unset($_SESSION); ) /** * Check if user logged in * @return boolean */ public function loggedIn()( return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id; ) /** * Check if the user is an administrator * @return boolean */ public function isAdmin()( return $this->rank() = = "administrator"; ) /** * Find user type, can be either administrator or regular * @return string */ public function rank()( if($this->orm->rank == 1)( return "administrator "; ) return "regular"; ) /** * A method that allows you to get private info * as properties of the User object * @param string $key The name of the property that gets accessed * @return mixed */ public function __get($key)( if(isset($this->orm->$key))( return $this->orm->$key; ) return null; ) )

Tokens are generated using the SHA1 algorithm and stored in the database. I'm using MySQL's time functions to set a 10-minute token expiration limit.

When the token passes the validation procedure, we directly tell the handler that we are only considering tokens that have not yet expired, stored in the token_validity column.

Please note that I am using the magic method __get docs library at the end of the file to intercept access to the properties of the User object.

Thanks to this, it becomes possible to access the information stored in the database, thanks to the properties $user->email, $user->token etc. In the following code snippet, let's take an example of how to use these classes.


Protected page

Another file that stores useful and necessary functionality is the file functions.php. There are several so-called helpers here - helper functions that allow you to create cleaner and more readable code in other files.

functions.php

Function send_email($from, $to, $subject, $message)( // Helper that sends email $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type: text /plain; charset=utf-8" . "\r\n"; $headers .= "From: ".$from . "\r\n"; return mail($to, $subject, $message, $headers ); ) function get_page_url()( // Get PHP file URL $url = "http".(empty($_SERVER["HTTPS"])?"":"s")."://".$_SERVER ["SERVER_NAME"]; if(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != "")( $url.= $_SERVER["REQUEST_URI"]; ) else( $url. = $_SERVER["PATH_INFO"]; ) return $url; ) function rate_limit($ip, $limit_hour = 20, $limit_10_min = 10)( // Number of login attempts in the last hour at this IP address $count_hour = ORM: :for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"1:00")") ->count(); // Number of login attempts in the last 10 minutes at this IP address $count_10_min = ORM::for_table("reg_login_attempt") ->where("ip", sprint f("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"0:10")") ->count(); if($count_hour > $limit_hour || $count_10_min > $limit_10_min)( throw new Exception("Too many login attempts!"); ) ) function rate_limit_tick($ip, $email)( // Create a new entry in the table counting number of login attempts $login_attempt = ORM::for_table("reg_login_attempt")->create(); $login_attempt->email = $email; $login_attempt->ip = sprintf("%u", ip2long($ip)); $login_attempt->save(); ) function redirect($url)( header("Location: $url"); exit; )

Functions rate_limit and rate_limit_tick monitor the number of authorization attempts for the elapsed period of time since the first attempt. The login attempt is recorded in the database in the reg_login_attempt column. These functions are called when the form data is being processed and submitted, as you can see from the following code snippet.

The code below is taken from the file index.php and it handles the form submission. It returns a JSON response which is in turn processed by jQuery in a file assets/js/script.js which we have already discussed earlier.

index.php

Try( if(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"]))( // Output a JSON header header("Content-type: application/json"); // Is this email address valid if(!isset($_POST["email"]) || !filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))( throw new Exception("Please enter a valid email."); ) // Check. Is the user allowed to log in, has he exceeded the number of allowed connections? (functions.php file for more information) rate_limit($_SERVER["REMOTE_ADDR"]); // Record this login attempt rate_limit_tick($_SERVER["REMOTE_ADDR"], $ _POST["email"]); // Send an email to the user $message = ""; $email = $_POST["email"]; $subject = "Your Login Link"; if(!User::exists($email) )( $subject = "Thank You For Registering!"; $message = "Thank you for registering at our site!\n\n"; ) // Attempt to authorize or register a user $user = User::loginOrRegister($_POST[ "email"]); $message.= "You can login from this URL:\n" ; $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n"; $message.= "The link is going to expire automatically after 10 minutes."; $result = send_email($fromEmail, $_POST["email"], $subject, $message); if(!$result)( throw new Exception("There was an error sending your email. Please try again."); ) die(json_encode(array("message" => "Thank you! We\"ve sent a link to your inbox. Check your spam folder as well.")))); ) ) catch(Exception $e)( die(json_encode(array("error"=>1, "message" => $e->getMessage() ))); )

After successful authorization/registration, the code above will send the user a link for authorization. The token becomes available because it is passed as a variable in the generated link by the method $_GET with marker tkn

index.php

If(isset($_GET["tkn"]))( // Is this token valid for authorization? $user = User::findByToken($_GET["tkn"]); if($user)( // Yes , is. Redirect to the protected page $user->login(); redirect("protected.php"); ) // No, the token is not valid. Redirect to the page with the login/registration form redirect("index.php "); )

$user->login()

will create the necessary variables for the session, so that the user, viewing subsequent pages of the site, will remain authorized all the time.

Similarly, the processing of the function to exit the system is arranged.

index.php

If(isset($_GET["logout"]))( $user = new User(); if($user->loggedIn())( $user->logout(); ) redirect("index.php") ; )

At the end of the code, I again redirected to index.php, so the parameter ?logout=1 passed by URL is not required.

Our file index.php requires additional protection - we do not want people who have ever logged into the system to see the registration form again. For these purposes, we use the method $user->loggedIn().

index.php

$user = new User(); if($user->loggedIn())( redirect("protected.php"); )

Finally, here is a piece of code that allows you to protect the pages of your site and make it available only after authorization.

protected.php

// To secure each page on your site, include a file // main.php and create a new User object. That's how easy it is! require_once "includes/main.php"; $user = new User(); if(!$user->loggedIn())( redirect("index.php"); )

After this check, you can be sure that the user was successfully authorized. You can also access stored information in the database using object properties $user. To display the user's email and status, use this code:

echo "Your email: ".$user->email; echo "Your rank: ".$user->rank();

Method rank() is used here because numbers are usually stored in the database (0 for a normal user, 1 for an administrator) and we need to convert this data into the statuses to which they belong, which is what this method helps us with.

To make a regular user an administrator, simply edit the user entry through phpMyAdmin (or any other program that allows you to manage databases). The administrator status does not give any privileges, in this example, the page will display that you are an administrator - and that's it.

But what to do with it - it remains at your discretion, you can write and compose code yourself that sets certain privileges and opportunities for administrators.

We're done!

With this incredibly super quasi simple shape, we are done! You can use it in your PHP sites, it's quite simple. You can also modify it for yourself and make it the way you want.

The material was prepared by Denis Malyshok specifically for the site site

P.S. Do you want to move further in mastering PHP and OOP? Take a look at premium tutorials on various aspects of website building, including PHP programming, as well as a free course on building your PHP CMS system from scratch using OOP:

Liked the material and want to thank?
Just share with your friends and colleagues!


Today we will look at the exploitation of a critical 1day vulnerability in the popular Joomla CMS, which exploded on the Internet at the end of October. We will talk about vulnerabilities with numbers CVE-2016-8869, CVE-2016-8870 and CVE-2016-9081. All three come from the same piece of code that languished in the bowels of the framework for five long years, waiting in the wings to break free and bring chaos, hacked sites and tears of innocent users of this Joomla. Only the most valiant and courageous developers, whose eyes are red from the light of monitors, and the keyboards are littered with bread crumbs, were able to challenge the raging evil spirits and lay their heads on the altar of fixes.

WARNING

All information is provided for informational purposes only. Neither the editors nor the author are responsible for any possible harm caused by the materials of this article.

How it all started

On October 6, 2016, Demis Palma created a topic on Stack Exchange, in which he asked: why, in fact, in Joomla version 3.6, there are two methods for registering users with the same name register() ? The first is in the UsersControllerRegistration controller and the second is in UsersControllerUser . Damis wanted to know if the UsersControllerUser::register() method is being used somewhere, or if it's just an evolutionary anachronism left over from the old logic. He was concerned about the fact that even if this method is not used by any view, it can still be called with a generated request. To which I received a response from the developer under the nickname itoctopus, who confirmed that the problem really exists. And sent a report to Joomla developers.

Further events developed most rapidly. On October 18, Joomla developers accept a report from Damis, who by that time had drafted a PoC that allows user registration. He published a note on his website, where he spoke in general terms about the problem he found and his thoughts on it. On the same day, a new version of Joomla 3.6.3 is released, which still contains vulnerable code.

After that, Davide Tampellini spins the bug to the state of registering not a simple user, but an administrator. And already on October 21, a new case arrives to the Joomla security team. It already talks about privilege escalation. On the same day, an announcement appears on the Joomla website that on Tuesday, October 25, the next version with the serial number 3.6.3 will be released, which fixes a critical vulnerability in the system core.

On October 25, the Joomla Security Strike Team finds the latest problem created by a piece of code discovered by Damis. Then, a commit from October 21 with the inconspicuous name Prepare 3.6.4 Stable Release is pushed to the main branch of the official Joomla repository, which fixes the unfortunate bug.

After this coming out, numerous interested individuals join the developers' cabal - they begin to spin the vulnerability and prepare sploits.

On October 27, researcher Harry Roberts uploads a ready-made exploit to the Xiphos Research repository that can upload a PHP file to a server with a vulnerable CMS.

Details

Well, the prehistory is over, let's move on to the most interesting - analysis of the vulnerability. As an experimental version, I installed Joomla 3.6.3, so all line numbers will be relevant for this version. And all the paths to the files that you see next will be indicated relative to the root of the installed CMS.

Thanks to Damis Palma's find, we know that there are two methods that perform user registration in the system. The first one is used by the CMS and is located in the /components/com_users/controllers/registration.php:108 file. The second one (the one we need to call) lives in /components/com_users/controllers/user.php:293 . Let's take a closer look at it.

286: /** 287: * Method to register a user. 288: * 289: * @return boolean 290: * 291: * @since 1.6 292: */ 293: public function register() 294: ( 295: JSession::checkToken("post") or jexit(JText::_ ("JINVALID_TOKEN")); ... 300: // Get the form data. 301: $data = $this->input->post->get("user", array(), "array"); . .. 315: $return = $model->validate($form, $data); 316: 317: // Check for errors 318: if ($return === false) 319: ( ... 345: / / Finish the registration.346: $return = $model->register($data);

Here I have left only interesting lines. The full version of the vulnerable method can be viewed in the Joomla repository.

Let's figure out what happens during a normal user registration: what data is sent and how it is processed. If user registration is enabled in the settings, then the form can be found at http://joomla.local/index.php/component/users/?view=registration .


A legitimate user registration request looks like the following screenshot.


The com_users component is responsible for working with users. Pay attention to the task parameter in the request. It has the format $controller.$method . Let's look at the file structure.

Script names in folder controllers match the names of the called controllers. Since our request now has $controller = "registration" , the file will be called registration.php and its register() method.

Attention, the question is: how to transfer registration processing to a vulnerable place in the code? You probably already guessed. The names of the vulnerable and real methods are the same (register), so we just need to change the name of the called controller. And where is the vulnerable controller? That's right, in the file user.php. It turns out $controller = "user" . Putting it all together, we get task = user.register . Now the registration request is processed by the method we need.


The second thing we need to do is send the data in the correct format. Everything is simple here. Legitimate register() expects an array from us called jform , in which we pass data for registration - name, login, password, mail (see the screenshot with the request).

  • /components/com_users/controllers/registration.php: 124: // Get the user data. 125: $requestData = $this->input->post->get("jform", array(), "array");

Our child receives this data from an array named user .

  • /components/com_users/controllers/user.php: 301: // Get the form data. 302: $data = $this->input->post->get("user", array(), "array");

Therefore, we change the names of all parameters in the request from jfrom to user .

Our third step is to find a valid CSRF token, since without it there will be no registration.

  • /components/com_users/controllers/user.php: 296: JSession::checkToken("post") or jexit(JText::_("JINVALID_TOKEN"));

It looks like an MD5 hash, and you can take it, for example, from the authorization form on the site /index.php/component/users/?view=login .


Now you can create users through the desired method. If everything worked out, then congratulations - you just exploited a vulnerability CVE-2016-8870"Missing permission check for registering new users."

Here's what it looks like in the "working" register() method from the UsersControllerRegistration controller:

  • /components/com_users/controllers/registration.php: 113: // If registration is disabled - Redirect to login page. 114: if (JComponentHelper::getParams("com_users")->get("allowUserRegistration") == 0) 115: ( 116: $this->setRedirect(JRoute::_("index.php?option=com_users&view= login", false)); 117: 118: return false; 119: )

And so in the vulnerable:

  • /components/com_users/controllers/user.php:

Yep, no way.

To understand the second, much more serious problem, let's send the request we formed and see how it is executed in various parts of the code. Here is the piece that is responsible for validating user submitted data in the worker method:

Continued available to members only

Option 1. Join the "site" community to read all the materials on the site

Membership in the community during the specified period will give you access to ALL Hacker materials, increase your personal cumulative discount and allow you to accumulate a professional Xakep Score rating!

Last modified on July 23rd, 2019 by Vincy.

User registration or sign up is an integral part of many web applications and it is critical to get it right for the success of the application. It is the starting point of user engagement with your application.

It should be as simple as possible with the best UI / UX. Implementing user registration functionality using PHP is a simple task and I will walk you through the steps with example in this article.

What is inside?

How does this PHP user registration example work?

This example code can be separated into 3 parts.

  1. Getting user information via a HTML form.
  2. Validating user submitted information on form submit.
  3. Database handling to save registered user to the database after validation.

The third step will be executed after ensuring that the user is not added already. This data uniqueness validation will be performed based on their email and username entered by them.

During registration we generally collect user information, who are ready to register with our application. Some of them will be mandatory and some of them will be optional.

So, this functionality may also include validation part to ensure about the non-emptiness and the format of the user data. The validation could be done either in the client-side or server-side.

Having validation at server-side is always better. You can choose to have it in client-side also for the ease of use of the users. But having at the server-side is not optional and a minimum requirement.

file structure

HTML form to allow user to register

In this example, the registration form contains the fields Username, Name(Display Name), Password and Email. It also has the Confirm Password field to let the user to reenter his password for the confirmation. These two passwords will be compared later at the time of a .

By submitting this form, the user is expected to agree to the terms and conditions. So a checkbox field is added before the Register button for ensuring it.

PHP User Registration Form

sign up
"; } ?>
">
">
">
I accept terms and conditions

And the styles are

Body ( font-family: Arial; color: #333; font-size: 0.95em; ) .form-head ( color: #191919; font-weight: normal; font-weight: 400; margin: 0; text-align : center; font-size: 1.8em; ) .error-message ( padding: 7px 10px; background: #fff1f2; border: #ffd5da 1px solid; color: #d6001c; border-radius: 4px; margin: 30px 0px 10px 0px ; ) .success-message ( padding: 7px 10px; background: #cae0c4; border: #c3d0b5 1px solid; color: #027506; border-radius: 4px; margin: 30px 0px 10px 0px; ) .demo-table ( background: #ffffff; border-spacing: initial; margin: 15px auto; word-break: break-word; table-layout: auto; line-height: 1.8em; color: #333; border-radius: 4px; padding: 20px 40px ;width: 380px;border: 1px solid;border-color: #e5e6e9 #dfe0e4 #d0d1d5; ) .demo-table .label ( color: #888888; ) .demo-table .field-column ( padding: 15px 0px; ) .demo-input-box ( padding: 13px; border: #CCC 1px solid; border-radius: 4px; width: 100%; ) .btnRegister ( padding: 13px; background-color: #5d9cec; color: #f5f7fa; cursor: pointer; border-radius: 4px width: 100% border: #5791da 1px solid; font-size: 1.1em ) .response-text ( max-width: 380px; font-size: 1.5em; text-align: center; background: #fff3de; padding: 42px; border-radius: 3px; border: #f5e9d4 1px solid; font-family : arial; line-height: 34px; margin: 15px auto; ) .terms ( margin-bottom: 5px; )

How to validate user information on form submit

A server-side form validation script is added to this example for validating the user registration data. This PHP validation script will be called on submitting the registration form.

This script validates all form fields to check the non-emptiness for each field. Then it validates the user email format using PHP's filter_var() function.

As the registration includes a password confirmation feature, the password comparison will take place at this part of this example.

Finally, the validation script will check if the user accepts term and condition by checking the appropriate box on the form.

Once all the validation is completed by returning boolean true, then the actual registration process will take place.

Function validateMember() ( $valid = true; $errorMessage = array(); foreach ($_POST as $key => $value) ( ​​if (empty($_POST[$key])) ( $valid = false; ) ) if($valid == true) ( ​​if ($_POST["password"] != $_POST["confirm_password"]) ( $errorMessage = "Passwords should be same."; $valid = false; ) if (! isset ($error_message)) ( if (! filter_var($_POST["userEmail"], FILTER_VALIDATE_EMAIL)) ( $errorMessage = "Invalid email address."; $valid = false; ) ) if (! isset($error_message)) ( if (! isset($_POST["terms"])) ( $errorMessage = "Accept terms and conditions."; $valid = false; ) ) ) else ( $errorMessage = "All fields are required."; ) if ( $valid == false) ( return $errorMessage; ) return; )

PHP MySQL code to access database to save registered user

Server-side user form validation

This is the PHP entry point to handle all the server-side script to validate form and to handle database operations based on the validation result.

validateMember($username, $displayName, $password, $email); if (empty($errorMessage)) ( $memberCount = $member->isMemberExists($username, $email); if ($memberCount == 0) ( $insertId = $member->insertMemberRecord($username, $displayName, $ password, $email); if (! empty($insertId)) ( header("Location: thankyou.php"); ) ) else ( $errorMessage = "User already exists."; ) ) ) ?>

Check if user already exists

The isMemberExists() function is used to check the user data uniqueness based on their email and the username. If the entered username or email there exists in the user database, then the registration process will be stopped by returning and acknowledgment.

This acknowledgment will notify that the “user already exists”. the code is,

Function isMemberExists($username, $email) ( $query = "select * FROM registered_users WHERE user_name = ? OR email = ?"; $paramType = "ss"; $paramArray = array($username, $email); $memberCount = $this->ds->numRows($query, $paramType, $paramArray); return $memberCount; )

Insert member data to the database

If it returns 0 then it means that there is no such users exist with the email or the username entered. And so, the registration data will be inserted to the database. The following code shows the member insert method.

Function insertMemberRecord($username, $displayName, $password, $email) ( $passwordHash = md5($password); $query = "INSERT INTO registered_users (user_name, display_name, password, email) VALUES (?, ?, ?, ? )"; $paramType = "ssss"; $paramArray = array($username, $displayName, $passwordHash, $email); $insertId = $this->ds->insert($query, $paramType, $paramArray); return $insertId; )

DataSource.php

This is the generic data source class in PHP to perform database operations. It includes functions to connect database and execute various queries to get database result, row count, execute insert and more.

This datasource class is generic and kept as simple as possible. It is efficient and I use it in my most of the micro projects and tutorials. You are free to download and use it.

important thing is never forget to use the Prepared Statements. It helps you to safeguard from SQL injection attacks and it is the first step in terms of implementing security in a web application.

conn = $this->getConnection(); ) /** * If connection object is needed use this method and get access to it. * Otherwise, use the below methods for insert / update / etc. * * @return \mysqli */ public function getConnection() ( $conn = new \mysqli(self::HOST, self::USERNAME, self::PASSWORD, self::DATABASENAME); if (mysqli_connect_errno()) ( trigger_error ("Problem with connecting to database."); ) $conn->set_charset("utf8"); return $conn; ) /** * To get database results * @param string $query * @param string $paramType * @ param array $paramArray * @return array */ public function select($query, $paramType="", $paramArray=array()) ( $stmt = $this->conn->prepare($query); if(! empty($paramType) && !empty($paramArray)) ( $this->bindQueryParams($sql, $paramType, $paramArray); ) $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows > 0) ( while ($row = $result->fetch_assoc()) ( $resultset = $row; ) ) if (! empty($resultset)) ( return $resultset; ) ) / ** * To insert * @param string $query * @param string $paramType * @param array $paramArray * @return int */ public function insert($query, $paramType, $p aramArray) ( print $query; $stmt = $this->conn->prepare($query); $this->bindQueryParams($stmt, $paramType, $paramArray); $stmt->execute(); $insertId = $stmt->insert_id; return $insertId; ) /** * To execute query * @param string $query * @param string $paramType * @param array $paramArray */ public function execute($query, $paramType="", $paramArray=array()) ( $ stmt = $this->conn->prepare($query); if(!empty($paramType) && !empty($paramArray)) ( $this->bindQueryParams($stmt, $paramType="", $paramArray= array()); ) $stmt->execute(); ) /** * 1. Prepares parameter binding * 2. Bind prameters to the sql statement * @param string $stmt * @param string $paramType * @param array $ paramArray */ public function bindQueryParams($stmt, $paramType, $paramArray=array()) ( $paramValueReference = & $paramType; for ($i = 0; $i< count($paramArray); $i ++) { $paramValueReference = & $paramArray[$i]; } call_user_func_array(array($stmt, "bind_param"), $paramValueReference); } /** * To get database results * @param string $query * @param string $paramType * @param array $paramArray * @return array */ public function numRows($query, $paramType="", $paramArray=array()) { $stmt = $this->conn->prepare($query); if(!empty($paramType) && !empty($paramArray)) ( $this->bindQueryParams($stmt, $paramType, $paramArray); ) $stmt->execute(); $stmt->store_result(); $recordCount = $stmt->num_rows; return $recordCount; ) )

Database script

This database script has the create statement for the registered_users table. Import this script in your development environment to run this code.

Table structure for table `registered_users` -- CREATE TABLE IF NOT EXISTS `registered_users` (`id` int(8) NOT NULL AUTO_INCREMENT, `user_name` varchar(255) NOT NULL, `first_name` varchar(255) NOT NULL, ` last_name` varchar(255) NOT NULL, `password` varchar(25) NOT NULL, `email` varchar(55) NOT NULL, `gender` varchar(20) NOT NULL, PRIMARY KEY (`id`));

If the registration form validation fails, then the error message will be shown to the user as like as below.

Comments to “PHP User Registration Form (Sign up) with MySQL Database”

    Hi Vincy, I get the following errors when running the register code, please help.

    INSERT INTO registered_users (user_name, display_name, password, email) VALUES (?, ?, ?, ?)
    Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in C:\xampp\htdocs\PHP\JAMII-CASH\DataSource.php on line 136

    Fatal error: Uncaught Error: Call to a member function execute() on boolean in C:\xampp\htdocs\PHP\JAMII-CASH\DataSource.php:99 Stack trace: #0 C:\xampp\htdocs\PHP\JAMII -CASH\Member.php(83): Phppot\DataSource->insert('INSERT INTO reg…', 'ssss', Array) #1 C:\xampp\htdocs\PHP\JAMII-CASH\index.php(20 ): Phppot\Member->insertMemberRecord('chuki10', 'Ray', '202020', ' [email protected]…’) #2 (main) thrown in C:\xampp\htdocs\PHP\JAMII-CASH\DataSource.php on line 99