How To Build a PHP Contact Form - Part 1 of 3

The file structure

We create an App and public_html directory. The App will be used to store the database connection later on. Everything inside the public_html directory will be accessible by the public. Inside the public_html directory we have the header.php and the footer.php files which will store the base HTML and then the meat of our contact form will be built in the basic.php file. file structure for PHP app

We will use bootstrap as the base of our contact form. This allows you the freedom to build on top of this project in a standarized manner.

Split the base bootstrap template between your header and footer file. So in your header.php file will look like the example below.

<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <title>Simple contact form</title> </head> <body>

Then in your footer.php file you will have the following.

<!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script> </body> </html>

Now the bulk of our app will be in basic.php - in essence all that we are doing is taking user input, clean it and then store it in a variable that we use to populate the e-mail template. It's that simple.

  • Receive user input
  • Clean user input
  • Store user input
  • Send E-mail

We need a form to take the user input

<form action="" method="post"> <div class="form-group"> <label for="">First Name</label> <input type="text" class="form-control" id="first_name" name="first_name"> </div> <div class="form-group"> <label for="">Last Name</label> <input type="text" class="form-control" id="last_name" name="last_name"> </div> <div class="form-group"> <label for="">Email address</label> <input type="email" class="form-control" id="email" name="email"> </div> <div class="form-group"> <label for="message">Message</label> <textarea class="form-control" id="message" name="message" rows="3"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form>

Now we need a PHP function that will clean this user input for us to make it safe to use in the database.

function clean_input($user_input) { $user_input = trim($user_input); $user_input = stripslashes($user_input); $user_input = htmlspecialchars($user_input); return $user_input; }

Now we need to make sure that the user input is actually filled in. We also need to make sure what is filled in is actually valid and what we wanted.

if(!empty($_POST['email'])) { // check if this is a legit email address if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $email = clean_input($_POST['email']); } else { array_push($errors, "The e-mail address is not valid."); } } else { array_push($errors, "E-mail cannot be empty."); }

If everything is filled in then we can proceed to send the e-mail.

// send the email if(count($errors) == 0) { // wrap the message $message = wordwrap($message); // send the mail $sent = mail("youtube@erikthiart.com", "Contact form submission", $message); if($sent) { $confirm_message = 'Thank you for your message, '.$first_name.' - we have received it sucessfully.'; } else { // display a useful message. (dont lose the client) array_push($errors, "Your message was not sent - please contact us directly (error: 44)"); } }

Now we bring everything together

<?php // handle the post request if($_SERVER['REQUEST_METHOD'] == 'POST') { // initialize everything // set the error variable array $errors = array(); // functions function clean_input($user_input) { $user_input = trim($user_input); $user_input = stripslashes($user_input); $user_input = htmlspecialchars($user_input); return $user_input; } // check if the user input is empty, clean it up and set the variables. // first name if(!empty($_POST['first_name'])) { $first_name = clean_input($_POST['first_name']); } else { array_push($errors, "First name cannot be empty."); } // last name if(!empty($_POST['last_name'])) { $last_name = clean_input($_POST['last_name']); } else { array_push($errors, "Last name cannot be empty."); } // email address if(!empty($_POST['email'])) { // check if this is a legit email address if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) { $email = clean_input($_POST['email']); } else { array_push($errors, "The e-mail address is not valid."); } } else { array_push($errors, "E-mail cannot be empty."); } // form message if(!empty($_POST['message'])) { $message = clean_input($_POST['message']); } else { array_push($errors, "Please enter your message."); } // send the email if(count($errors) == 0) { // wrap the message $message = wordwrap($message); // creat email body $mail_body = ' Full name: '.$first_name.' '.$last_name.' <br> E-mail Address: '.$email.' <br> Message: '.$message.' '; // send the mail $sent = mail("youtube@erikthiart.com", "Contact form submission", $message); if($sent) { $confirm_message = 'Thank you for your message, '.$first_name.' - we have received it sucessfully.'; } else { // display a useful message. (dont lose the client) array_push($errors, "Your message was not sent - please contact us directly (error: 44)"); } } } ?> <?php include 'header.php'; ?> <div class="jumbotron jumbotron-fluid"> <div class="container"> <h1 class="display-4">Simple contact form</h1> </div> </div> <div class="container"> <div class="row"> <div class="col-sm"> <?php if(!empty($errors)): ?> <div class="alert alert-danger" role="alert"> <?php foreach($errors as $error) { echo $error . "<br>"; } ?> </div> <?php endif;?> <?php if(!empty($confirm_message)):?> <div class="alert alert-success" role="alert"> <?=$confirm_message;?> </div> <?php endif;?> <form action="" method="post"> <div class="form-group"> <label for="">First Name</label> <input type="text" class="form-control" id="first_name" name="first_name"> </div> <div class="form-group"> <label for="">Last Name</label> <input type="text" class="form-control" id="last_name" name="last_name"> </div> <div class="form-group"> <label for="">Email address</label> <input type="email" class="form-control" id="email" name="email"> </div> <div class="form-group"> <label for="message">Message</label> <textarea class="form-control" id="message" name="message" rows="3"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </div> </div> <?php include 'footer.php'; ?>

Click here to access part 2 of this tutorial where we will be adding phpMailer to the project.

Some articles you might also be interested in...

How to block ads on your network using Pi-Hole and a Raspberry Pi
How to block ads on your network using Pi-Hole and a Raspberry Pi

With Pi-Hole you can block in-app advertisements. Network-level blocking allows you to block ads in non-traditional places such as mobile apps and smart TVs, regardless of your hardware or OS and since advertisements are blocked before they are downloaded, network performance is improved and will feel faster. Pi-hole is a black hole for Internet advertisements.

Read The Article
Sonoff SNZB-02 Zigbee Temperature & Humidity Sensor
Sonoff SNZB-02 Zigbee Temperature & Humidity Sensor

Enclosed in the same shell, SNZB-02 Zigbee temperature & Humidity sensor reports back every couple of minutes. The sensor is powered by CR2450 3V battery. The extra capacity means that the sensor will last a really long time. I have a heater connected to eWeLink app and, once I added a hub (absolutely required) this thing has performed well. The heater is controlled within +- 1°C. That's another thing, eWeLink only provides temperature readings in °C with no option for °F. I'm thinking about placing another sensor on the outside of the window so that I can control based on outdoor temperature as well.

Read The Article
Xiaomi Mijia 1080P 170 Degree Smart IP Camera with AI Human Detection
Xiaomi Mijia 1080P 170 Degree Smart IP Camera with AI Human Detection

I know this review is long, but I wanted to include all the details to help you decide. This smart security camera from Xiaomi had so much going for it, I still believe there a route for Xiaomi to redeem themselves and make this camera available to its full potential by issuing a firmware update to remove the restrictions and allow RTSP access from the Xiaomi camera.

Read The Article