PHP Form

Summary: in this tutorial, you will learn how HTML forms work and how to process form data in PHP.

Introduction to PHP form processing

To create a form, you use the <form> element as follows:

<form action="form.php" method="post"> </form>
Code language: HTML, XML (xml)

The <form> element has two important attributes:

  • action: specifies the URL that processes the form submission. In this example, the form.php will process the form.
  • method: specifies the HTTP method for submitting the form. The most commonly used form methods are POST and GET. In this example, the form method is post.

The form method is case-insensitive. It means that you can use either post or POST. If you don’t specify the method attribute, the form element will use the get method by default.

Typically, a form has one or more input elements including text, password, checkbox, radio button, select, file upload, etc. The input elements are often called form fields.

An input element has the following important attributes name, type, and value. The name attribute will be used for accessing the value in PHP.

HTTP POST method

If a form uses the POST method, the web browser will include the form data in the HTTP request’s body. After submitting the form, you can access the form data via the associative array $_POST in PHP.

For example, if a form has an input element with the name email, you can access the email value in PHP via the $_POST['email']. If the form doesn’t have an email input, the $_POST won’t have any element with the key 'email'.

To check if the form data contains the email, you use the isset() like this:

<?php if(isset($_POST['email']) { // process email }
Code language: HTML, XML (xml)

The following shows a form with an input element:

<form action="form.php" method="post"> <div> <label for="email">Email:</label> <input type="email" id="email" name="email" /> </div> <button type="submit">Submit</button> </form>
Code language: HTML, XML (xml)

In the form.php file, you can access the email value as follows:

<?php if (isset($_POST['email'])) { var_dump($_POST['email']); }
Code language: HTML, XML (xml)

HTTP GET method

When you submit a form using the GET method, you can access the form data in PHP via the associative array $_GET.

Unlike the POST method, the GET method appends the form data in the URL that processes the form. Suppose the URL that processes the form is http://localhost/form.php. When you enter the email as hello@phptutorial.net and submit a form, you’ll see that the email value is appended to the URL like this:

http://localhost/form.php?email=hello%40phptutorial.net
Code language: plaintext (plaintext)

Note that the @ is encoded as %40 in the URL.

In PHP, you can use the isset() to check if the form data contains the email:

<?php if(isset($_GET['email']) { // process email }
Code language: HTML, XML (xml)

If the form has multiple input elements, the web browser will append the form inputs to the URL in the following format:

http://localhost/form.php?name1=value1&name2=value2&name3=value3
Code language: plaintext (plaintext)

The following shows the same form that has an email input. However, the form uses the GET method instead:

<form action="form.php" method="get"> <div> <label for="email">Email:</label> <input type="email" id="email" name="email" /> </div> <button type="submit">Submit</button> </form>
Code language: HTML, XML (xml)

And the following shows the form.php file:

<?php if (isset($_GET['email'])) { var_dump($_GET['email']); }
Code language: HTML, XML (xml)

Note that both $_POST and $_GET arrays are superglobal variables. It means that you can access them anywhere in the script.

HTTP GET or POST

In general, you should use the GET method when the form only retrieves data from the server. For example, a search form that allows users to search for information should use the GET method.

When you have a form that causes a change in the server, you should use the POST method. For example, a form that allows users to subscribe to a newsletter should use the POST method.

PHP form example

The following index.php contains a form that allows users to subscribe to a newsletter:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="css/style.css"> <title>PHP Form Demo</title> </head> <body> <main> <form action="subscribe.php" method="post"> <div> <label for="name">Name:</label> <input type="text" name="name" required="required" placeholder="Enter your name" /> </div> <div> <label for="name">Email:</label> <input type="email" name="email" required="required" placeholder="Enter your email" /> </div> <button type="submit">Subscribe</button> </form> </main> </body> </html>
Code language: HTML, XML (xml)

The form uses the POST method and submits the data to the subscribe.php page. It has two input elements with type text and email.

Before submitting the form to the server, the web browser checks if all required fields are filled out, in the correct format. This is known as client-side form validation.

To validate data on the client-side, you can use either HTML5 form validation or JavaScript validation. However, you should never rely on client-side validation as a security measure.

The client-side validation’s purpose is to help legitimate users to enter data in the correct format. However, it doesn’t prevent malicious users from entering bad data that potentially harm the application. Therefore, it’s mandatory to implement server-side validation.

The following shows the code of the subscribe.php file:

<?php //--------------------------------------------- // WARNING: this doesn't include sanitization // and validation //--------------------------------------------- if (isset($_POST['name'], $_POST['email'])) { $name = $_POST['name']; $email = $_POST['email']; // show the $name and $email echo "Thanks $name for your subscription.<br>"; echo "Please confirm it in your inbox of the email $email."; } else { echo 'You need to provide your name and email address.'; }
Code language: PHP (php)

How it works.

  • First, check if the name and email are in the $_POST array using the isset() function.
  • Second, show a thank you message.

If you enter the name as John and email as john.doe@example.com, you’ll see the following message on the subscribe.php page:

Thanks John for your subscription. Please confirm it in your inbox of the email john.doe@example.com
Code language: plaintext (plaintext)

Escaping the output

The subscribe.php page directly displays the form data. If malicious hackers intentionally enter bad data, the page won’t work properly.

For example, if the following JavaScript code is entered in the name field and the form is submitted.

<script>alert('Hello');</script>
Code language: HTML, XML (xml)

…you’ll see that the page displays an alert.

Imagine that the script doesn’t just show an alert but loads the malicious code from another server to the user’s web browser, the risk is higher. This type of attack is called cross-site scripting (XSS) attack.

Therefore, before displaying user input on a webpage, you should always escape the data. To do that, you use the htmlspecialchars() function:

<?php //--------------------------------------------- // WARNING: this doesn't include sanitization // and validation //--------------------------------------------- if (isset($_POST['name'], $_POST['email'])) { $name = htmlspecialchars($_POST['name']); $email = htmlspecialchars($_POST['email']); // show the $name and $email echo "Thanks $name for your subscription.<br>"; echo "Please confirm it in your inbox of the email $email."; } else { echo 'You need to provide your name and email address.'; }
Code language: PHP (php)

Note that we will also show you how to sanitize and validate form data in the next tutorial.

PHP self-processing form

Sometimes, you want to include both form and logic for handling form submission in a single PHP file. This form is often referred to as a self-processing form.

To create a self-processing form, you can use the $_SERVER['REQUEST_METHOD'] that returns the request method e.g., GET or POST.

If the $_SERVER['REQUEST_METHOD']  is GET, you show the form. And if the $_SERVER['REQUEST_METHOD']  is POST, you process it. For example:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/style.css"> <title>PHP Form</title> </head> <body> <main> <?php if ($_SERVER['REQUEST_METHOD'] === 'GET') : ?> <form action="<?php htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post"> <div> <label for="name">Name:</label> <input type="text" name="name" required="required" placeholder="Enter your name" /> </div> <div> <label for="name">Email:</label> <input type="email" name="email" required="required" placeholder="Enter your email" /> </div> <button type="submit">Subscribe</button> </form> <?php else : ?> <?php //--------------------------------------------- // WARNING: this doesn't include sanitization // and validation //--------------------------------------------- if (isset($_POST['name'], $_POST['email'])) { $name = htmlspecialchars($_POST['name']); $email = htmlspecialchars($_POST['email']); // show the $name and $email echo "Thanks $name for your subscription.<br>"; echo "Please confirm it in your inbox of the email $email."; } else { echo 'You need to provide your name and email address.'; } ?> <?php endif ?> </main> </body> </html>
Code language: PHP (php)

However, mixing PHP & HTML is not always a good practice.

To make the code more organized, you can create the following file & directory structure:

. ├── css │ └── style.css ├── inc │ ├── header.php │ ├── footer.php │ ├── get.php │ ├── post.php │ └── .htaccess └── index.php
Code language: plaintext (plaintext)

The index.php file in the root directory will include the header.php and footer.php.

If the request method is GET, the index.php file loads the form in the get.php file. Otherwise, it loads the code from the post.php file for processing the POST request.

index.php

The following shows the index.php file:

<?php require __DIR__ . '/inc/header.php'; $request_method = strtoupper($_SERVER['REQUEST_METHOD']); if ($request_method === 'GET') { require __DIR__ . '/inc/get.php'; } elseif ($request_method === 'POST') { require __DIR__ . '/inc/post.php'; } require __DIR__ . '/inc/footer.php';
Code language: HTML, XML (xml)

header.php

The header.php contain the first part of the page:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="css/style.css"> <title>PHP Form</title> </head> <body> <main>
Code language: HTML, XML (xml)

footer.php

The footer.php file contains the enclosing tags of the page:

</main> </body> </html>
Code language: HTML, XML (xml)

get.php

The get.php file contains the form. The $_SERVER['PHP_SELF'] returns the file name of the currently executing script.

For example, if the executing script is https://www.phptutorial.net/app/form/index.php, the $_SERVER['PHP_SELF'] returns /app/form/index.php.

However, the $_SERVER['PHP_SELF'] cannot be trusted since and it’s vulnerable to XSS attacks. Therefore, you should always escape it using the htmlspecialchars() function.

The following shows the get.php file:

<form action="<?php htmlspecialchars($_SERVER['PHP_SELF']) ?>" method="post"> <div> <label for="name">Name:</label> <input type="text" name="name" placeholder="Enter your name" /> </div> <div> <label for="name">Email:</label> <input type="email" name="email" placeholder="Enter your email" /> </div> <div> <button type="submit">Subscribe</button> </div> </form>
Code language: HTML, XML (xml)

post.php

The following shows the post.php file that handles the form submission:

<?php //----------------------------------------------------- // WARNING: this doesn't include sanitization // and validation //----------------------------------------------------- if (isset($_POST['name'], $_POST['email')) { $name = htmlspecialchars($_POST['name']); $email = htmlspecialchars($_POST['email']); // show the $name and $email echo "Thanks $name for your subscription.<br>"; echo "Please confirm it in your inbox of the email $email."; } else { echo 'You need to provide your name and email address.'; }
Code language: PHP (php)

.htaccess

The .htaccess file prevents direct access to the files in the inc directory. It’s relevant only to the Apache webserver.

Deny from all
Code language: JavaScript (javascript)

By using the .htaccess file, you cannot browse the file directly from the inc folder. For example: https://www.phptutorial.net/app/form/inc/get.php

Here’s the final version of the form.

Summary

  • Use the <form> tag to create an HTML form.
  • Specify the URL that processes the form submission in the action attribute.
  • Use either GET or POST method for the method attribute of the form for submission.
  • Use the $_GET or $_POST to access the form data.
  • Use the htmlspecialchars() function to escape the user input before showing it on a webpage.
Did you find this tutorial useful?