PHP script not validating input

608 views Asked by At

Why is this script not validating e-mail address, name and phone number? It is sending the e-mail, but not notifying me of the intentional errors in the input fields. (This script is called from html form tag).

<?php
// define variables and set to empty values
$emailErr = $nameErr =  $phoneErr = "";
$email = $name = $phone = $message = "";

function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
   if (empty($_POST["email"])) {
     $emailErr = "Email is required";
   } else {
     $email = test_input($_POST["email"]);
     // check if e-mail address is well-formed
     if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
       $emailErr = "Invalid email format";
     }
   }

   if (empty($_POST["name"])) {
     $nameErr = "Name is required";
   } else {
     $name = test_input($_POST["name"]);
     // check if name only contains letters and whitespace
     if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
       $nameErr = "Only letters and white space allowed";
     }
   }

   if (empty($_POST["phone"])) {
     $phone = "";
   } else {
     $phone = test_input($_POST["phone"]);
     // check if phone number is valid (this regular expression also allows dashes in the phone number)
     if (!preg_match("/^[0-9+'('+')'+ '-' ]*$/",$phone)) {
       $phoneErr = "Invalid Phone Number";
     }
   }

  $email = $_REQUEST['email'] ;
  $name = $_REQUEST['name'] ;
  $phone = $_REQUEST['phone'] ;
  $message = $_REQUEST['message'] ;

  mail( "[email protected]", "Contact Us Inquiry",
    $message, "From: $email" );
  header( "Location: http://omitted.com/ThankYou.html" );
}


?>

updated 6/23/15 almost midnight EDT Form now validates input, but I want it prettier.

Posting contents of HTML form tag and script tag to show you that I want the email, name and phone number errors to appear to the right of the input boxes for those fields and if there are errors, I want to stay on the Contact_Us page. How do I do that? (Also posting working php script below the HTML form contents.)

In Head tag:

<style>
.error {color: #00a261;}
</style>

In Body tag:

<p><span class="error">* required field. </span></p>

<form method="post" name="contact_us_form" action="contact_us_e_mail.php">  
<div align="center">
   Email: &nbsp;<input name="email" type="text" border-style="solid" border-width="1px" style="border-color:#00a261" value=""/><span class="error">&nbsp;*&nbsp; 
   <?php 
   echo $emailErr; ?> 
   </span><br /><br />
   Name: &nbsp;<input name="name" type="text" border-style="solid" border-width="1px" style="border-color:#00a261" value=""/><span class="error">&nbsp;*&nbsp; 
   <?php echo $nameErr; ?> 
   </span><br /><br />
   Phone: &nbsp;<input name="phone" type="text" border-style="solid" border-width="1px" style="border-color:#00a261" value=""/><span class="error">&nbsp;*&nbsp; 
    <?php echo $phoneErr; ?> 
   </span><br /><br />
   Message:<br />
   <textarea name="message" border-style: solid style="border-color:#00a261" rows="15" cols="80">
   </textarea>
   <br />
    <input type="submit" value="Submit"/>
</form>

Revised php script (called contact_us_e_mail.php):

    <?php
// define variables and set to empty values
$emailErr = $nameErr = $phoneErr = "";
$email = $name = $phone = $message = "";

function test_input($data) {
   $data = trim($data);
   $data = stripslashes($data);
   $data = htmlspecialchars($data);
   return $data;
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
   if (empty($_POST["email"])) {
     $emailErr = "Email is required";
   } else {
     $email = test_input($_POST["email"]);
     // check if e-mail address is well-formed
     if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
       $emailErr = "Invalid email format. Please use browser's back button and correct.";
     }
   }

   if (empty($_POST["name"])) {
     $nameErr = "Name is required";
   } else {
     $name = test_input($_POST["name"]);
     // check if name only contains letters and whitespace
     if (!preg_match("/^[a-zA-Z ]*$/",$name)) {
       $nameErr = "Only letters and white space allowed in Name. Please use browser's back button and correct.";
     }
   }

   if (empty($_POST["phone"])) {
     $phoneErr = "Phone is required";
   } else {
     $phone = test_input($_POST["phone"]);
     // check if phone number is valid (this regular expression also allows dashes in the phone number)
     if (!preg_match("/^[0-9+'('+')'+'-']*$/",$phone)) {
       $phoneErr = "Invalid Phone Number. Please use browser's back button and correct.";
     }
   }

  $email = $_REQUEST['email'] ;
  $name = $_REQUEST['name'] ;
  $phone = $_REQUEST['phone'] ;
  $message = $_REQUEST['message'] ;

if($nameErr == '' && $phoneErr == '' && $emailErr == ''){
  mail( "[email protected]", "Contact Us Inquiry",
    $message, "From: $email" );
   header( "Location: http://omitted.com/ThankYou.html" );
}else{
   echo $emailErr, "<br />"; 
   echo $nameErr, "<br />";  
   echo $phoneErr, "<br />";    
   //$errorList = $nameErr . ' ' . $phoneErr . ' ' . $emailErr;
   //header( "Location: http://omitted.com/Contact_Us.html" );
}

}

?>
2

There are 2 answers

0
Patrick Murphy On

Well you are setting the variables $nameErr, $phoneErr, $emailErr but you are never testing them.

You should wrap your mail statement in an if like this:

if($nameErr == '' && $phoneErr == '' && $emailErr == ''){
  mail( "[email protected]", "Contact Us Inquiry", $message, "From: $email" );
  header( "Location: http://omitted.com/ThankYou.html" );
}else{
   $errorList = $nameErr . ' ' . $phoneErr . ' ' . $emailErr;
   header( "Location: http://omitted.com/errors.php?errorList=" . $errorList );
}
0
enhzflep On

Here's one approach to cracking that particular nut. The key is to check for the existance of the form's vars at the beginning of the script, before deciding what to present to the user. Yet another alternative would be to submit the form using the FormData object and AJAX. You could return a JSON object and then with JS on the client-side, decide whether to hide/show error messages and to re-direct to another page upon success, if desired.

The way that the die functions is one of the important keys to such an approach. As mentioned in the comments, it stops any further processing of the file - whether it be simply emitting html or if it be evaluating php code.

If the 'validation' (that I dont perform) fails, you'll get an asterisk next to the fields with problems. It will also throw the acceptable fields back into their inputs in the form, avoiding the need to type all of the info again for the sake of an error in just one of the inputs.

Just throw it onto a server and have a play. I'm a bit in two minds about such an approach. On one hand, it ties everything all together in a single location. On the other hand, you can end up with 4 languages in a single file (php,html,css,js) and something that can fairly quickly become a little er, unpleasant to maintain.

test.php

<?php
/*
    sample that contains a form that will sumbit to itself
*/
    // nothing entered in the POST array - this means the page has been loaded as a result of a request originating
    // somewhere _other_ than the form in this page.
    // we'll need to display the page ready for a 'first-visit'
    if (count($_POST) == 0)
    {
        //echo ('$_POST array is empty!<br>');
        $username = $email = $message = '';
    }

    // no validation here, I'm assuming all are okay. You need to validate for yourself in this block of code.
    // you'll notice that submitting an empty form gives us 3 vars in the POST array, all of which are empty strings
    else
    {
        $username = $email = $message = '';
        if (isset($_POST['username']) == true)
            $username = $_POST['username'];

        if (isset($_POST['email']) == true)
            $email = $_POST['email'];

        if (isset($_POST['message']) == true)
            $message = $_POST['message'];

        // use this block or the 7 lines above - they have the same effect.
        /*
        $username = isset($_POST['username']) == true ? $_POST['username'] : "";
        $email = isset($_POST['email']) == true ? $_POST['email'] : "";
        $message = isset($_POST['message']) == true ? $_POST['message'] : "";
        */

        if ( strlen($username) == 0)
            $usernameNotPresent = true;

        if ( strlen($email) == 0)
            $emailNotPresent = true;

        if ( strlen($message) == 0)
            $messageNotPresent = true;

        if (( isset($usernameNotPresent)==false) && (isset($emailNotPresent)==false) && (isset($messageNotPresent) == false))
        {
            doSendMail();

            // execution/parsing of the file will stop here. This has 2 effects.
            // 1. Any further php code wont be interpreted and then run
            // 2. Any html that follows a call to die wont be shown.

            // Therefore, if we get here that means we've sent the email and there's no use in showing the
            // email form.
            // provided nothing has been output yet, you could also re-direct to another page with a call
            // to the function header
            die;
        }
    }

function doSendMail()
{
    // ToDo:
    //      send the email here



    // print a message telling the user of the outcome of trying to send the email.
    echo "<p>Email successfully sent, please check your inbox</p>";
}

?>
<!doctype html>
<html>
<head>
<script>
</script>
<style>
.wrapper
{
    display: inline-block;
}
#myForm
{
    text-align: center;
}
#myForm > input, #myForm > textarea
{
    /* display: block; */
    margin-bottom: 16px;
    width: 170px;
    text-align: left;
}
#myForm > input[type='submit']
{
    width: 50%;
    text-align: center;
}
</style>
</head>
<body>
    <div class='wrapper'>
        <form id='myForm' method='post' action='' >     <!-- an empty action attribute submits the form back to itself -->
            <?php
                if (isset($usernameNotPresent))
                    echo "<input type='text' name='username' placeholder='enter username'><span class='error'>*</span></br>";
                else
                    echo "<input type='text' name='username' placeholder='enter username' value='$username'></br>";
            ?>
            <?php
                if (isset($emailNotPresent))
                    echo "<input type='text' name='email' placeholder='enter email address'><span class='error'>*</span></br>";
                else
                    echo "<input type='text' name='email' placeholder='enter email address' value='$email'></br>";
            ?>
            <?php
                if (isset($messageNotPresent))
                    echo "<textarea name='message' placeholder='enter your message'></textarea><span class='error'>*</span></br>";
                else
                    echo "<textarea name='message' placeholder='enter your message'>$message</textarea></br>";
            ?>
            <div><input type='submit' value='GO'/></div>
        </form>
    </div>
</body>
</html>