Jump to content
Larry Ullman's Book Forums

Contact Form Problem - Scrubber + Filter + Error Messages


Recommended Posts

Hi everyone,

I bought the book PHP and MySQL for Dynamic Web Sites, but I need some help with regards to my form. I'm hoping someone could please help me – thanks!

This is a contact form that gets sent to an email address. I would like to combine the spam_scrubber() function from script 13.1 with the filter extensions. I also added some error messages that get displayed if the form isn't filled in.

There is a problem with the email. If I submit the form but the email input isn't filled in, the error message pops up – as it should. If I add some random text, and submit the form, the text disappears. Presumably because the filter extension is working properly? I would like to display a message such as “invalid email” if someone tries to submit the form without a valid email address.

In other words, I need two error messages for my email:
1) if the email input is empty
2) if the email input doesn't contain a valid email address.

Currently my email error variable looks like this (if the input is empty and the form is submitted):
<span><?php if (empty($scrubbed['email'])) echo $no_email;?></span>

I tried to add code that would display an “invalid email” message if the value has been sent through the filter extension. Something like:
$validemail = filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL);
  if ($validemail) {
    echo $invalid_email;
  }

I'm still learning PHP so the above code did not work.

Thank you for your help!


Here is the code:
PS: I left out the scrubber function code to save space.

// I initialized the some variables for the error messages
$no_name = $no_email  = "";

// Check for form submission:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {

// I assigned messages to the error variables
$no_name = "You forgot to enter your name";
$no_email = "You forgot to enter your email";

// scrubber begins
    function spam_scrubber($value) {

        
        // Clear $scrubbed (so that the form's not sticky):
        $scrubbed = array();

// cleared error messages after form has been submitted
        $no_name = "";
                        $no_email = "";
    
    }
    
} // End of main isset() IF.




// Create the HTML form:
?>
<p>Please fill out this form to contact me.</p>
<form action="email.php" method="post">
    <p>Name:
    <span><?php if (empty($scrubbed['name'])) echo $no_name;?></span>
    </p>
    <input type="text" name="name" size="30" maxlength="60" value=
    "<?php if (isset($scrubbed['name'])) echo filter_var($scrubbed['name'],     FILTER_SANITIZE_STRING); ?>" />
    
    <p>Email Address:
    <span><?php if (empty($scrubbed['email'])) echo $no_email;?></span>
    </p>
    <input type="text" name="email" size="30" maxlength="80" value=
    "<?php if (isset($scrubbed['email'])) echo filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL); ?>" />
    
   

Link to comment
Share on other sites

The presentation of the code is a bit confusing, but a couple suggestions...

 

- Why distinguish between not submitting an email address at all (i.e., empty) and submitting something that's not syntactically valid? The problem is the same in both cases.

- How about using an error message as your flag variable? Like so:

$errors = array();
$scrubbed = /* scrub the form data */;
if (!isset($scrubbed['email']) || !filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL)) {
    $errors['email'] = 'Please enter a valid email address.';
}

Then you can do this in your form:

<?php if (isset($errors['email'])) echo $errors['email'];?>
Link to comment
Share on other sites

Hi Larry,

 

thank you so much for replying! Please excuse the late reply.

 

So I tried the code you provided but I'm still experiencing some issues.

 

Should the email code look like this?

 

<p>Email Address:

<span><?php if (isset($errors['email'])) echo $errors['email'];?></span>

</p>

<input type="text" name="email" size="30" maxlength="80" value=

"<?php if (isset($scrubbed['email'])) echo filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL); ?>" />

 

If I enter a valid email address and press send, the error message still remains. Also, how would I change the following code, so that everything is scrubbed, filtered and validated before the body of the email is created?

 

// Minimal form validation:

if (!empty($scrubbed['email']) && !empty($scrubbed['name']) ) {

  // Create the body:

  $body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";

 

Thank you. I appreciate your help!

Link to comment
Share on other sites

No, it should be this:

<input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($scrubbed['email'])) echo $scrubbed['email']; ?>" />

As for why you're still seeing an error message, I'd need to see the complete code.

 

And I don't understand your last question.

Link to comment
Share on other sites

Hi Larry,

 

thank you for getting back to me!

 

I'm a bit confused as to what I should do.

 

If I only include this for my email:

<input type="text" name="email" size="30" maxlength="80" value="<?php if (isset($scrubbed['email'])) echo $scrubbed['email']; ?>" />

then where do I add the error message you gave to me in your first reply?

<?php if (isset($errors['email'])) echo $errors['email'];?>

I would like to have the error message pop-up next to the name of the specific form input, which is why I put it between the span tags.

<p>Email Address:
<span><?php if (empty($scrubbed['email'])) echo $no_email;?></span>
</p>
<input type="text" name="email" size="30" maxlength="80" value=
"<?php if (isset($scrubbed['email'])) echo filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL); ?>" /> 

And what about running ($scrubbed['email']) through a filter?

 

 

You also asked me about my last question. In your book on p407, ch13 security methods, you describe the following code:

if (!empty($scrubbed['name']) && !empty($scrubbed['email']) && !empty($scrubbed['comments']) ) {
	
		// Create the body:
		$body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";

From my understanding this means that if ($scrubbed['name']), ($scrubbed['email']) etc are all not empty, then the values can be assigned to the $body variable. In my form all of the values would need to be not only not empty but have also been run through an appropriate filter. Should I therefore have the following in my code?

	if (!empty($scrubbed['email']) && filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL)
&& !empty($scrubbed['name']) && filter_var($scrubbed['name'], FILTER_SANITIZE_STRING))
  {


Herewith my code:

<?php # Script 13.1 - email.php #2
// This version now scrubs dangerous strings from the submitted input.

// Check for form submission:



$errors = array();


if ($_SERVER['REQUEST_METHOD'] == 'POST') {


if (!isset($scrubbed['name']) || !filter_var($scrubbed['name'], FILTER_SANITIZE_STRING)) {
    $errors['name'] = 'Please enter a name.';
}



if (!isset($scrubbed['email']) || !filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL)) {
    $errors['email'] = 'Please enter a valid email address.';
}

	/* The function takes one argument: a string.
	* The function returns a clean version of the string.
	* The clean version may be either an empty string or
	* just the removal of all newline characters.
	*/
	function spam_scrubber($value) {

		// List of very bad values:
		$very_bad = array('to:', 'cc:', 'bcc:', 'content-type:', 'mime-version:', 'multipart-mixed:', 'content-transfer-encoding:');
	
		// If any of the very bad strings are in 
		// the submitted value, return an empty string:
		foreach ($very_bad as $v) {
			if (stripos($value, $v) !== false) return '';
		}
	
		// Replace any newline characters with spaces:
		$value = str_replace(array( "\r", "\n", "%0a", "%0d"), ' ', $value);
	
		// Return the value:
		return trim($value);

	} // End of spam_scrubber() function.

	// Clean the form data:
	$scrubbed = array_map('spam_scrubber', $_POST);

	// Minimal form validation:
	if (!empty($scrubbed['email']) && !empty($scrubbed['name']) ) {
	
		// Create the body:
		$body = "Name: {$scrubbed['name']}\n\nComments: {$scrubbed['comments']}";

		// Make it no longer than 70 characters long:
		$body = wordwrap($body, 70);
	
		// Send the email:
		mail('your_email@example.com', 'Contact Form Submission', $body, "From: {$scrubbed['email']}");

		// Print a message:
		echo '<p><em>Thank you for contacting me. I will reply some day.</em></p>';
		
		// Clear $scrubbed (so that the form's not sticky):
		$scrubbed = array();
		
	
	} 
	
} // End of main isset() IF.

// Create the HTML form:
?>
<p>Please fill out this form to contact me.</p>
<form action="email.php" method="post">

	
	<p>Name:
	<span><?php if (isset($errors['name'])) echo $errors['name'];?></span>
	</p>
	<input type="text" name="name" size="30" maxlength="60" value=
	"<?php if (isset($scrubbed['name'])) echo filter_var($scrubbed['name'], FILTER_SANITIZE_STRING); ?>" />
	
	
	<p>Email Address:
	<span><?php if (isset($errors['email'])) echo $errors['email'];?></span>
	</p>
	<input type="text" name="email" size="30" maxlength="80" value=
	"<?php if (isset($scrubbed['email'])) echo filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL); ?>" />
	
	
	<p><input type="submit" name="submit" value="Send!" /></p>
</form>
</body>
</html>

Thank you again for your help.

Link to comment
Share on other sites

Lot of questions in one post. Will do my best to answer them...

 

 

> Then where do I add the error message you gave to me in your first reply?
 
You put that wherever you want the error message to appear:
<p>Email Address:
<span><?php if (isset($errors['email'])) echo $errors['email'];?></span>
</p>
You wrote:
<?php if (isset($scrubbed['email'])) echo filter_var($scrubbed['email'], FILTER_VALIDATE_EMAIL); ?>" /> 
And what about running ($scrubbed['email']) through a filter?

 

 
There's no point in running it through a filter there. There you should output more or less what the user inputted (which is how sticky forms generally work). The filtering is for validation, which you're not doing at that point in the code. 
 
> In my form all of the values would need to be not only not empty but have also been run through an appropriate filter. Should I therefore have the following in my code?
 
The code you have would work, but is messy. There are other examples in the book where I validate form elements individually and then check a master variable to know whether the form was filled out or not (e.g., I check if the errors array is still empty). You should check out those examples for a cleaner way of doing what you're trying to do.
Link to comment
Share on other sites

 Share

×
×
  • Create New...