Programmer's Interview 101: Create a Simple Single Page Contact Form Using PHP

Problem

Create a PHP single page named contact.php that accepts inputs and sends email to a certain recipient. Basically, this serves as the usual contact page used on a PHP based website.

Analysis

We can divide the problem into two parts:
  • A script part that verifies the input and sends to an email
  • A layout or UI part that accepts inputs

The Code

PHP

This is the server side code that sends the message to the email using the mail(). This PHP function allows you to send e-mails directly from a script. The sample below sends a simple text email.

NOTE: The code requires you to have an installed and working email system in your server to function. It is also important to set the php.ini configurations properly. Setting this up will not be discussed in this tutorial.

<?php
// disregard error reporting on the front end
error_reporting(0);

// checks if post exists, then send the message to $to email
if($_POST['subject']){
 $to = 'EMAIL@HERE.COM'; // replace this with a proper email
 $subject = $_POST['subject'];
 $from = $_POST['email'];
 $message = $_POST['message'];
 $message = "Name : ".$name."\nSite: ".$_POST['site']."\nEmail : ".$from."\nMessage : ".$message;
 $headers = "From:" . $from;
 mail($to,$subject,$message,$headers);
}

?>

HTML


This part of the code gives you a HTML layout that accepts inputs. It is then sent to the same URL location ($_SERVER['PHP_SELF']) where the action above will take place. Though, upon clicking the submit button, a script validation will take place first before proceeding.

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" onSubmit="return validate(this);">
  
    <fieldset id="user-details">
  <label for="name">Name *</label><br/>
  <input type="text" name="name" id="name" value="" required="required" /><br/>
    
  <label for="email">Email *</label><br/>
  <input type="email" name="email" id="email" value="" required="required"  /> <br/>
    
  <label for="site">Site</label> <br/>
  <input type="url" name="site" id="site" value="" /><br/>
    
  <label for="subject">Subject *</label><br/>
  <input type="text" name="subject" id="subject" value="" required="required" /><br/>
  
  <label for="message">Message </label><br/>
  <textarea name="message" id="message" rows="0" cols="0"></textarea><br/>
  
  <input type="submit" value="Send Message" name="submit" id="submit" class="submit" style="width:220px;" />
    </fieldset>
    
</form>

JavaScript

The script validation is merely a checking of data on the client side before passing it to the server functions. Here simple validation takes place in case the browser doesn't support the HTML5 code we used above.

<script>
/* 
 * THIS IS JUST A BASIC JAVASCRIPT CONFIRMATION ON THE FRONT END.
 * YOU CAN ACTUALLY DO A BETTER CHECKING ON THE SERVER SIDE USING PHP ON THIS SAME PAGE.
 */

function validate(form){
 var error="";

 if(form.name.value == ""){
  error=error+"Name could not be blank.\n";
 }

 // checks 
 var email = document.getElementById('email').value;
 if(form.email.value == "")
  error=error+"Email could not be blank.\n";
 else{
  atpos = email.indexOf("@");
  dotpos = email.lastIndexOf(".");
  if (atpos &lt; 1 || ( dotpos - atpos &lt; 2 )){
   error=error+"Invalid Email.\n";
  }
 }

 if(form.subject.value == ""){
  error=error+"Subject could not be blank.\n";
 }

 if(error!=""){
  alert('Errors found. Form could not be sent:\n'+error); return false;
 }
 else{
  alert('Sending Message Now.');
 }
}
</script>


Summary of the code

Here is how it will looks like together:

<?php
// disregard error reporting on the front end
error_reporting(0);

// checks if post exists, then send the message to $to email
if($_POST['subject']){
 $to = 'EMAIL@HERE.COM'; // replace this with a proper email
 $subject = $_POST['subject'];
 $from = $_POST['email'];
 $message = $_POST['message'];
 $message = "Name : ".$name."\nSite: ".$_POST['site']."\nEmail : ".$from."\nMessage : ".$message;
 $headers = "From:" . $from;
 mail($to,$subject,$message,$headers);
}

?>

<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" onSubmit="return validate(this);">
  
    <fieldset id="user-details">
  <label for="name">Name *</label><br/>
  <input type="text" name="name" id="name" value="" required="required" /><br/>
    
  <label for="email">Email *</label><br/>
  <input type="email" name="email" id="email" value="" required="required"  /> <br/>
    
  <label for="site">Site</label> <br/>
  <input type="url" name="site" id="site" value="" /><br/>
    
  <label for="subject">Subject *</label><br/>
  <input type="text" name="subject" id="subject" value="" required="required" /><br/>
  
  <label for="message">Message </label><br/>
  <textarea name="message" id="message" rows="0" cols="0"></textarea><br/>
  
  <input type="submit" value="Send Message" name="submit" id="submit" class="submit" style="width:220px;" />
    </fieldset>
    
</form>

<script>
/* 
 * THIS IS JUST A BASIC JAVASCRIPT CONFIRMATION ON THE FRONT END.
 * YOU CAN ACTUALLY DO A BETTER CHECKING ON THE SERVER SIDE USING PHP ON THIS SAME PAGE.
 */

function validate(form){
 var error="";

 if(form.name.value == ""){
  error=error+"Name could not be blank.\n";
 }

 // checks 
 var email = document.getElementById('email').value;
 if(form.email.value == "")
  error=error+"Email could not be blank.\n";
 else{
  atpos = email.indexOf("@");
  dotpos = email.lastIndexOf(".");
  if (atpos &lt; 1 || ( dotpos - atpos &lt; 2 )){
   error=error+"Invalid Email.\n";
  }
 }

 if(form.subject.value == ""){
  error=error+"Subject could not be blank.\n";
 }

 if(error!=""){
  alert('Errors found. Form could not be sent:\n'+error); return false;
 }
 else{
  alert('Sending Message Now.');
 }
}
</script>

Now just add some basic HTML tags and CSS styling and the page should now be fine! :)

Download contact.php file sample

2 comments :

  1. Hello, I would like to comment on this solution. I give tests for new programmers all the time. A couple glaring mistakes in this example would make me consider the candidate twice. First, turning off error reporting. That's a very bad choice. If you're in production, you might want to turn off display errors, but definitely not stop the error reporting. Next, instead of checking if($_POST['.... you'll want to use 'isset' - if (isset($_POST['.... - because this will not generate errors if it is not a post. Finally, you'll want to filter for new lines or validate email addresses for the $from email. It is possible that a malicious user could put in an address like "test@test.com\nbcc:other@addresses.com" - which would allow this form to be used to spam other users by adding additional headers.

    Thanks. -aaron

    ReplyDelete
  2. wow great analysis!

    Actually, regarding the isset and the one I've used, I usually advice to use isset too. Though, I honestly, forgot this function while I was doing the test code ( Probably because, I rarely use PHP :p ). So my initial reaction was to use something very basic. Thanks for mentioning though.

    Same with the email validation, I made it very simple but I'm definitely sure that there is a better way of doing things like using a regexp.

    Again thanks for the wonderful analysis @google-ce0b8eb62178eed49ebcd82a34c3cd5c:disqus :)

    ReplyDelete