PHP Form Script Issues

Hey everyone!!

I am having major spam issues with a PHP form script where they are breaking through by typing whatever they want as a phone number. To combat this, I wanted to add a function to my script that validates a phone number. But, I cannot figure out why it’s presenting me with issues, and could use a second pair of eyes.

I’ve called the function and written out the code to pop up an alert box that tells the user that the phone is invalid, but it doesn’t do that. Instead, the form goes to a blank page after hitting submit. I would like the code to execute by popping up an alert box that says “You must enter a valid phone number” if a user types something like 123456. This way, if a user does that, they cannot send the form email through.

The new sections of the script are highlighted in red. The $phone variable is called in the form HTML as an attribute whose name=“phone”.

<?php

[COLOR="#FF0000"]function phone_valid($phone) {
if (eregi( ? ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ? , $phone))
{ return TRUE; } else { return FALSE; }
}
[/COLOR]
function check_email_address($email) {
// check that there's one @ symbol, and that the lengths are right
    if (!preg_match("/^[^@]{1,64}@[^@]{1,255}$/", $email)) {    
// Email invalid because wrong number of characters in one section, or wrong number of @ symbols.
        return false;
    }
// Split it into sections to make life easier
    $email_array = explode("@", $email);
    $local_array = explode(".", $email_array[0]);
 
 
    for ($i = 0; $i < sizeof($local_array); $i++) {
        if (!preg_match("/^(([A-Za-z0-9!#$%&'*+\\/=?^_`{|}~-][A-Za-z0-9!#$%&'*+\\/=?^_`{|}~\\.-]{0,63})|(\\"[^(\\\\|\\")]{0,62}\\"))$/", $local_array[$i])) {
            return false;
        }
    }
    if (!preg_match("/^\\[?[0-9\\.]+\\]?$/", $email_array[1])) { // Check if domain is IP. If not, it should be valid domain name
        $domain_array = explode(".", $email_array[1]);
            if (sizeof($domain_array) < 2) {
                return false; // Not enough parts to domain
            }
        for ($i = 0; $i < sizeof($domain_array); $i++) {
            if (!preg_match("/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$/", $domain_array[$i])) {
                return false;
            }
        }
    }
 }
 
    return true;
}
 
$name = $_POST['name'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$comments = $_POST['comments'];

if( $name == true ) 
{
    $sender = $email;
    $receiver = "contactemail@someemail.com";
    $client_ip = $_SERVER['REMOTE_ADDR'];
    $email_body = "Name: $name \
\
Phone: $phone \
\
Email: $email \
\
Comments: \
\
$comments \
\
IP: $client_ip \
\
Contact Sent from http://websitename.com/";
    $newmessage = "Hi $name, \
\
Thank you for your inquiry. We will be in touch with you as quickly as possible. \
\
Please send us an email if you have any additional questions we can answer. Thank you.\
\
Phone: (123) 456-7891 \
\
Company Name \
Company Address \
Company City, Zip Code 
\
Website:http://www.websitename.com/ \
\
Your inquiry has been copied below. \
\
 --------------------- \
\
Name: $name \
Email: $email \
    \
Phone: $phone \
\
Details: \
\
$comments \
\
IP: $client_ip";
 
    $extra = "From: $sender\\r\
" . "Reply-To: $sender \\r\
" . "X-Mailer: PHP/" . phpversion();
    $extra2 = "From: $receiver\\r\
" . "Reply-To: $receiver \\r\
";

[COLOR="#FF0000"]if (phone_valid($phone) == false) {
echo "<script type="text/javascript">alert("You need to enter a valid phone number.");</script>";
}[/COLOR]

    if(check_email_address($email) == true) {
        if( mail( $receiver, "Client email questions", $email_body, $extra ) && mail( $sender, "Website name website inquiry has been received", $newmessage, $extra2 ) )
        {
            echo header("Location: contact-thank-you.php");
        }
    } else {
        echo header("Location: contact-failed.php");
    }
}

?>

Anyone…??

Hi,

The problem is that regardless of whether the phone number is valid or not, the script still executes this code:


if(check_email_address($email) == true) {
    if( mail( $receiver, "Client email questions", $email_body, $extra ) && mail( $sender, "Website name website inquiry has been received", $newmessage, $extra2 ) )
    {
        echo header("Location: contact-thank-you.php");
    }
} else {
    echo header("Location: contact-failed.php");
}

which results in the page being redirected to one of the two pages.

Note, by the way, that you don’t actually need the echo statement before you call the header() function.

Thank you so much, fretburner!!! What is the best way to re-write that last section so that 1. Mail is sent upon completion of correctly formatted information and 2. An alert pops up when Phone or email is not correct and prevents the form from being submitted, 3. Upon final completion of the form it redirects someone to the appropriate confirmation page?

Is this validation/email code part of the same page as the form? Or it’s a separate page that the form submits to?

It’s setup like this:

Index.html for example would be an html page using the php script.
sendmail.php is a separate file that’s globally called by index.html and all internal pages (this is a generic name and not the actual name of the file), so it’s all part of the same page. Index.html uses the script…page2.html uses the script…page3.html uses the script, and so on. But it’s all still part of the same page in one single form consisting of name, phone, email, and comments.

All of this code is in the sendmail.php file, which is of course called in index.html like this:

<form action="sendmail.php" method="post">...etc. etc.

Ideally, what I want to have happen is this script to redirect to a thank you page right after the phone & email fields are confirmed as correct and the email has been sent. Of course, if phone & email fields do not contain appropriate values, I would like to see pop-ups and the email to be stopped - stopping auto spambots in their tracks. Sorry about that…I haven’t coded the email field to display a pop up yet.

OK, well it’s going to be difficult to achieve with the way you currently have things set up. You can’t insert any script tags (or any content at all) into your index.html page from the sendmail.php script. If your form page was a .php file, you could pass the errors back in a session variable.

I suppose the best you could do in this instance would be to display the errors as output from sendmail.php and provide a link back to the form page so that the user can try again. It’s not ideal though, as the user has to start again from an empty form, which is especially annoying with longer forms.

The other thing you can do is to add JS validation on the form page itself, which will prevent the form being submitted unless the fields are filled in correctly. You should always do this in conjunction with server-side validation though, as some users may have JS disabled.

Oops!!! I completely forgot to mention - the pages are all php files. Not html files. I went back and double checked.

How do I pass the errors as a session variable while doing what I want to do? Can this be something like: If someone doesn’t fill out the phone number correctly it errors out and displays why on the confirmation page? I just want to prevent bots from getting through.

How do I accomplish this confirmation step by passing errors back???

Sure, that’s easy enough… I’d change the code to something like this:


<?php
// Validation functions not shown

$name = $_POST['name'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$comments = $_POST['comments'];

$isValid = TRUE;
$errors = array();

if (empty($name)) {
    $errors[] = "You must provide your name";
    $isValid = FALSE;
}

if (FALSE === check_email_address($email)) {
    $errors[] = "You must provide a valid email address";
    $isValid = FALSE;
}

if (FALSE === phone_valid($phone)) {
    $errors[] = "You need to enter a valid phone number";
    $isValid = FALSE;
}

if ($isValid) {
    
    // Assign email variables etc..

    if( mail( $receiver, "Client email questions", $email_body, $extra ) && mail( $sender, "Website name website inquiry has been received", $newmessage, $extra2 ) )
    {
        header("Location: contact-thank-you.php");
    } else {
        header("Location: contact-failed.php");
    }

} else { 
?>
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>My App</title>
</head>
<body>
    <h1>Form Submission Failed</h1>
    <ul>
    <?php foreach ($errors as $error): ?>
        <li><?php echo $error ?></li>
    <?php endforeach; ?>
    </ul>
    <p><a href="/index.php">Return to the form</a> to try again.</p>
</body>
</html>
<?php }

So we do the validation checks, and if any of them fail we assign an error string to the $errors array and set the $isValid flag to false. We then check the flag, and if it’s false then we skip sending the emails and output a list of the error messages and provide a link back to the form so the user can try again.

Well, if your users make a mistake in filling out the form, it’s good practice to redisplay the form, prefilled with the data they entered and any validation error messages, to allow them to try again. In that situation, if there are validation errors, we could pass them back to the form in a session variable. It’s your call if you want to go that route though.