PHP Contact Form (2023)

Summary: in this tutorial, you’ll learn how to build a contact form in PHP that includes form validation, sending email, honeypot, etc.

Introduction to the PHP contact form

A contact form allows visitors of a website to leave messages. Typically, a contact form has the name, email, subject, and message input fields.

The visitors need to fill out these fields and click the submit (or send) button to send a message. In PHP, you can validate the form data and send the entered message to an intended email address.

The contact form is a target for spammers who use spambots to send unsolicited messages for advertising, phishing, spreading malware, etc.

A spambot is software that automates the spam activities like filling out and submitting contact forms automatically.

To build a spam-free contact form, you can add a captcha to it. However, sometimes, captchas are impossible to read. As a result, they create a terrible experience for legitimate users.

To avoid using a captcha while protecting the contact from spam, you can use a honeypot to trick the spambots.

A honeypot is a field on the form that the visitor cannot see, but spambots can. When a spambot sees the honeypot field, it fills the field with a value. In PHP, you can check if the honeypot has a value and skip sending the message.

To create a honeypot, you need to have a CSS class that completely hide the honeypot field as follows:

(Video) 58: How to Create A PHP Contact Form | PHP Tutorial | Learn PHP Programming | HTML Contact Form

.user-cannot-see { display:none}

Code language: CSS (css)

And you have a honeypot field on the form:

<label for="nickname" aria-hidden="true" class="user-cannot-see"> Nickname <input type="text" name="nickname" id="nickname" class="user-cannot-see" autocomplete="off" tabindex="-1"></label>

Code language: HTML, XML (xml)

Note that the name of the honeypot should look legitimate. Recently, the spambot has become smarter that can detect the honeypot.

To deal with these smart spambots, you need a smart honeypot. For example, a smart honeypot may have a different name for each request. Also, its location on the form is changed randomly.

Create the contact form

We’ll build a contact form as shown in the following picture:

PHP Contact Form (1)

The contact form has the following features:

  • Form validation
  • Sending message via email
  • Prevent spam
  • Prevent double submit

First, create the following folders & files:

├── config| └── app.php├── css| └── style.css├── inc| ├── footer.php| ├── get.php| ├── header.php| ├── mail.php| └── post.php└── index.php

(Video) How to Make Contact Us Form in Php

Code language: PHP (php)


The header.php file contains the header part of the contact form:

<!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 Contact Form</title></head><body> <main>

Code language: HTML, XML (xml)


The footer.php file contains the enclosing tags of the header’s tags:


Code language: HTML, XML (xml)


The get.php file shows the contact form:

<?php if (isset($message)) : ?> <div class="alert alert-success"> <?= $message ?> </div><?php endif ?><form action="index.php" method="post"> <header> <h1>Send Us a Message</h1> </header> <div> <label for="name">Name:</label> <input type="text" value="<?= $inputs['name'] ?? '' ?>" name="name" id="name" placeholder="Full name"> <small><?= $errors['name'] ?? '' ?></small> </div> <div> <label for="email">Email:</label> <input type="email" name="email" id="email" value="<?= $inputs['email'] ?? '' ?>" placeholder="Email address"> <small><?= $errors['email'] ?? '' ?></small> </div> <div> <label for="subject">Subject:</label> <input type="subject" name="subject" id="subject" value="<?= $inputs['subject'] ?? '' ?>" placeholder="Enter a subject"> <small><?= $errors['subject'] ?? '' ?></small> </div> <div> <label for="message">Message:</label> <textarea id="message" name="message" rows="5"><?= $inputs['message'] ?? '' ?></textarea> <small><?= $errors['message'] ?? '' ?></small> </div> <label for="nickname" aria-hidden="true" class="user-cannot-see"> Nickname <input type="text" name="nickname" id="nickname" class="user-cannot-see" tabindex="-1" autocomplete="off"> </label> <button type="submit">Send Message</button></form>

Code language: PHP (php)

How it works.

First, display a success message if it is set:

<?php if (isset($message)) : ?> <div class="alert alert-success"> <?= $message ?> </div><?php endif ?>

(Video) Create A Contact Form with PHP That Can Actually Send Mails!

Code language: PHP (php)

Second, fill the input fields with data from the $inputs array. If the field has invalid data, show the error message from the $errors array.

Third, add a honeypot to the form:

<label for="nickname" aria-hidden="true" class="user-cannot-see"> Nickname <input type="text" name="nickname" id="nickname" class="user-cannot-see" tabindex="-1" autocomplete="off"></label>

Code language: PHP (php)


The post.php handles the form submission:

<?php// check the honeypot$honeypot = filter_input(INPUT_POST, 'nickname', FILTER_SANITIZE_STRING);if ($honeypot) { header($_SERVER['SERVER_PROTOCOL'] . ' 405 Method Not Allowed'); exit;}// validate name$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);$inputs['name'] = $name;if (!$name || trim($name) === '') { $errors['name'] = 'Please enter your name';}// validate email$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);$inputs['email'] = $email;if ($email) { $email = filter_var($email, FILTER_SANITIZE_EMAIL); if (!$email) { $errors['email'] = 'Please enter a valid email'; }} else { $errors['email'] = 'Please enter an email';}// validate subject$subject = filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_STRING);$inputs['subject'] = $subject;if (!$subject || trim($subject) === '') { $errors['subject'] = 'Please enter the subject';}// validate message$message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING);$inputs['message'] = $message;if (!$message || trim($message) === '') { $errors['message'] = 'Please enter the message';}

Code language: PHP (php)

The post.php checks the honeypot and returns the 405 HTTP status code if it detects the spambot. Otherwise, it sanitizes and validates the input fields, including name, email, subject, and message.


The config.php stores the configuration information e.g., the receiver’s email address:

<?phpreturn [ 'mail' => [ 'to_email' => '' ]];

Code language: PHP (php)


The mail.php gets the email address of the receiver from the app.php configuration file. It sends to the message entered in the contact form using the mail() function:

(Video) Working Contact Form in PHP with Validation & Email Sending

<?php// get email from the config file$config = require_once __DIR__ . '/../config/app.php';$recipient_email = $config['mail']['to_email'];// contact information$contact_name = $inputs['name'];$contact_email = $inputs['email'];$message = $inputs['message'];$subject = $inputs['subject'];// Email header$headers[] = 'MIME-Version: 1.0';$headers[] = 'Content-type: text/html; charset=utf-8';$headers[] = "To: $recipient_email";$headers[] = "From: $contact_email";$header = implode('\r\n', $headers);mail($recipient_email, $subject, $message, $header);

Code language: PHP (php)


The index.php file contains the main logic:

<?phpsession_start();$errors = [];$inputs = [];$request_method = strtoupper($_SERVER['REQUEST_METHOD']);if ($request_method === 'GET') { // show the message if (isset($_SESSION['message'])) { $message = $_SESSION['message']; unset($_SESSION['message']); } elseif (isset($_SESSION['inputs']) && isset($_SESSION['errors'])) { $errors = $_SESSION['errors']; unset($_SESSION['errors']); $inputs = $_SESSION['inputs']; unset($_SESSION['inputs']); } // show the form require_once __DIR__ . '/inc/get.php';} elseif ($request_method === 'POST') { // check the honeypot and validate the field require_once __DIR__ . '/inc/post.php'; if (!$errors) { // send an email require_once __DIR__ . '/inc/mail.php'; // set the message $_SESSION['message'] = 'Thanks for contacting us! We will be in touch with you shortly.'; } else { $_SESSION['errors'] = $errors; $_SESSION['inputs'] = $inputs; } header('Location: index.php', true, 303); exit;}

Code language: PHP (php)

How it works.

First, show the contact form if the HTTP request method is GET. Also, get the $message, $errors, and $inputs data from the $_SESSION.

Second, handle the form submission if the HTTP request method is POST, send an email if no error, and redirect to the contact form. Note that we use the PRG (Post-Redirect-Get) technique to avoid the double submit problem.

Did you find this tutorial useful?

(Video) Send email with PHP | Create a Working Contact Form Using PHP


1. PHP Front To Back [Part 15] - PHP Contact Form
(Traversy Media)
2. Working Contact Form Php | Php contact form to Gmail | Create Php contact form | Php Tutorial
(Tech2 etc)
3. How to create a contact form using PHP & MySQL | With Source Code | Brave Coder
(Brave Coder)
4. Create Working Contact Form Using HTML, CSS, PHP | Contact Form Design
(Easy Tutorials)
5. Create a Working Contact Form in HTML CSS JavaScript & PHP
6. Creating a PHP Contact Form
(Adam Thomas)
Top Articles
Latest Posts
Article information

Author: Jamar Nader

Last Updated: 09/07/2023

Views: 6669

Rating: 4.4 / 5 (75 voted)

Reviews: 90% of readers found this page helpful

Author information

Name: Jamar Nader

Birthday: 1995-02-28

Address: Apt. 536 6162 Reichel Greens, Port Zackaryside, CT 22682-9804

Phone: +9958384818317

Job: IT Representative

Hobby: Scrapbooking, Hiking, Hunting, Kite flying, Blacksmithing, Video gaming, Foraging

Introduction: My name is Jamar Nader, I am a fine, shiny, colorful, bright, nice, perfect, curious person who loves writing and wants to share my knowledge and understanding with you.