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, theform.php
will process the form.method
: specifies the HTTP method for submitting the form. The most commonly used form methods arePOST
andGET
. In this example, the form method ispost
.
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 [email protected]
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 theisset()
function. - Second, show a thank you message.
If you enter the name as John
and email as [email protected]
, 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 [email protected]
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
orPOST
method for themethod
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.