FRIHOSTFORUMSSEARCHFAQTOSBLOGSCOMPETITIONS
You are invited to Log in or Register a free Frihost Account!

How to build PHP mail form with Spam protection




If you read my first post in PHP blog (How to build simple upload form) then you have idea how I will build this mail form. If you didn't read it then we can start from begining. First of all we need form (mailform.php) and second mail processor (mailsender.php). These two files will do all stuff for us, like (sending, checking, SPAM protect, etc.). For communications between this two files we will use sessions and post. Ok, we can start. First is mailform.php.
Code:
<?php
session_start();
?>

Then we can create Spam protection. I am using one simple system what is in correlation with session and what we can check latter in mailsender.php.
Code:
$id = session_id();
$_SESSION['check'] = session_id();
$id = str_split($id, 5);
foreach($id as $key => $numIn) {
$res = strlen($numIn);
if($res!=5) {
 unset($id[$key]);
}
}
shuffle($id);
$_SESSION['spam'] = $id['0'];

First line collect session id. Second one fill session array with one definition. Third one cut id string in small five letter strings. Now we have an array. Because we haven’t idea how many letters contain session id we must remove out all strings what have less then 5 letters. This is working for us next foreach loop.
Then shuffle this array and print out one 5 letters string for checking. After this I am fill one more definition in session array (last line) because I need this information in mailsender.php. Now we can create simple form with four fields named: subject, mail, content, spam and button "Send". We will come back on mailform.php when we create mailsender.php.

Mailsender.php process our collected data and send back to mailform.php information for user. First we need to define return path and search array. This array contains all names what will come from mailform.php with post function when user press button "Send".
Code:
<?php
session_start();
$id = session_id();
$return = "mailform.php";
$search = array("subject", "mail", "content", "spam", "sent");
?>

Script will start checking user inputs in different ways. First is it session on the mailform.php same with session in mailsender.php.
Code:
if($id != $_SESSION['check']) {
$_SESSION['message'] = 1;
header("Location:$return");
exit;
}

In next foreach loop we will check two conditions. First, is all post fields have right names, and second is it this fields empty?
Code:
foreach($_POST as $key => $val) {
if(array_search($key, $search) === FALSE) {
$_SESSION['message'] = 1;
header("Location:$return");
exit;
}
if($val == "") {
$_SESSION['message'] = 2;
header("Location:$return");
exit;
}
}

It is right time to check Spam input. I will do this in two ways; first I will check are $_SESSION['spam'] the same like input and second are input part of session id.
Code:
if($_POST['spam'] != $_SESSION['spam'] || strpos($id, $_POST['spam']) === FALSE) {
$_SESSION['message'] = 3;
header("Location:$return");
exit;
}

Like you can see any error will return user to mailform.php. After this few form and session checking we must check one very important think: e-mail! I am here using preg_match function.
Code:
$regexp="/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i";
if (!preg_match($regexp, $_POST['mail'])) {
    $_SESSION['message'] = 4;
    header("Location:$return");
    exit;
}

Okay, now we are very near to the end of mailsender.php. But I am including here one more check.
Next check will check are button have right value (in our case "Send"). How you can see I don’t want to write the same definition for button name and value. Maybe this check is not necessary but gives me nice entrance for mail sending what is embed in else statement and in that case little bit more protected. If user passes this last check our script will start with sending mail but before sending we can clean subject and content inputs with htmlspecialchars and trim functions. On the end define your mail ($to) where you want to receive mails from your site.
Code:
$reply = $_POST['mail'];
$subject = htmlspecialchars($_POST['subject']);
$subject = trim($subject);
$content = htmlspecialchars($_POST['content']);
$content = trim($content);
$to = "some_mail@right_domain.com";
mail($to, $subject, $content, "From: $reply\r\n"."Reply-To: $reply\r\n");
$_SESSION['message'] = 5;
header("Location:$return");
exit;
}

When mail was sent script would return user on mailform.php. And we can go back to mailform.php and define messages for user. For messages we will use switch/case function.
Code:
//messages part
switch(@$_SESSION['message']) {
case "1": $message = "Sorry, some error occur! <br />"; break;
case "2": $message = "Please fill all fields. <br />"; break;
case "3": $message = "Your validation key is not correct. <br />"; break;
case "4": $message = "Your email address is not valid. <br />"; break;
case "5": $message = "Your e-mail has been sent successfully. <br />"; break;
default: "";
}
unset($_SESSION['message']);

Now you can see here full mailform.php:
Code:
<?php
session_start();

// prepare spam check
$id = session_id();
$_SESSION['check'] = session_id();
$id = str_split($id, 5);
foreach($id as $key => $numIn) {
$res = strlen($numIn);
if($res!=5) {
 unset($id[$key]);
}
}
shuffle($id);
$_SESSION['spam'] = $id['0'];

//messages part
switch(@$_SESSION['message']) {
case "1": $message = "Sorry, some error occur! <br />"; break;
case "2": $message = "Please fill all fields. <br />"; break;
case "3": $message = "Your validation key is not correct. <br />"; break;
case "4": $message = "Your email address is not valid. <br />"; break;
case "5": $message = "Your e-mail has been sent successfully. <br />"; break;
default: "";
}
unset($_SESSION['message']);
?>
<html>
<head>
<title>Mail Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<form name="form1" method="post" action="mailsender.php">
<?php
// display right message
echo @$message;
?>
Subject:<br />
<input type="text" name="subject">
<br /><br />
Your e-mail:<br />
<input type="text" name="mail">
<br /><br />Your message:<br />
<textarea name="content" rows="5"></textarea>
<br /><br />
Type:
<h2>
<?php echo $id['0']; ?>
<input type="text" name="spam" maxlength="5">
</h2>
<br />
<input type="submit" name="sent" value="Send">
</form>
</body>
</html>

And on THE END full script of mailsender.php:
Code:
<?php
session_start();
$id = session_id();
$return = "mailform.php";
$search = array("subject", "mail", "content", "spam", "sent");
if($id != $_SESSION['check']) {
$_SESSION['message'] = 1;
header("Location:$return");
exit;
}
foreach($_POST as $key => $val) {
if(array_search($key, $search) === FALSE) {
$_SESSION['message'] = 1;
header("Location:$return");
exit;
}
if($val == "") {
$_SESSION['message'] = 2;
header("Location:$return");
exit;
}
}
if($_POST['spam'] != $_SESSION['spam'] || strpos($id, $_POST['spam']) === FALSE) {
$_SESSION['message'] = 3;
header("Location:$return");
exit;
}
$regexp="/^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i";
if (!preg_match($regexp, $_POST['mail'])) {
    $_SESSION['message'] = 4;
    header("Location:$return");
    exit;
}
if(strpos($_POST['sent'], "Send") === FALSE) {
$_SESSION['message'] = 1;
header("Location:$return");
exit;
} else {
$reply = $_POST['mail'];
$subject = htmlspecialchars($_POST['subject']);
$subject = trim($subject);
$content = htmlspecialchars($_POST['content']);
$content = trim($content);

$to = "some_mail@right_domain.com"; // type here right email

mail($to, $subject, $content, "From: $reply\r\n"."Reply-To: $reply\r\n");
$_SESSION['message'] = 5;
header("Location:$return");
exit;
}
?>


Good luck! Sonam



2 blog comments below

You can also use the program CoffeeCup Web Form Builder, It worked for me Very Happy
You only have to delete the Adds of Coffeecup when you have the Trial Version, you can do that in the ccmt.php file Very Happy

Good Luck Smile
bmldesign on Tue Mar 25, 2008 7:06 pm
Because eregi function has been DEPRECATED as of PHP 5.3.0. I am update this script with preg_match function.

Sonam
sonam on Mon Aug 09, 2010 5:31 pm



FRIHOST HOME | FAQ | TOS | ABOUT US | CONTACT US | SITE MAP
© 2005-2011 Frihost, forums powered by phpBB.