Creating an Error Reporter

This tutorial will guide you through creating a form that allows people to report errors (typos etc) they find on your website (as previously seen on jemjabella.co.uk).

The first step is to create the actual form. We need three fields: page URL, error and correction. This allows visitors to pinpoint exactly where and what the error is. The basic HTML for this form would be:

<form action="error.php?page=process" method="post"><p>
<label><input type="text" id="page" name="page" /> Page URL</label><br />
<label><input type="text" id="error" name="error" /> Error</label><br />
<label><input type="text" id="correction" name="correction" /> Correction</label><br />
<input type="submit" name="submit" id="submit" value="Send" />
</p></form>

The most important part of that form at the moment is action="error.php?page=process". This tells our form where it will be processed. To save space, we can use the same page with a bit of PHP to separate the form and the processing. We’re going to use a switch() statement for this:

<?php
switch ($_GET['page']) {
	case "process":
		// process form
	break;
	default:
		// show form
	break;
} ?>

The switch statement takes part of the URL using the PHP superglobal array $_GET, and shows a section of code depending on what the value of ‘page’ is. As our form is targetted at page=process, we can assume that this is what the visitor will try and access — thus allowing us to make a “process” section, or case. The beauty of a switch() statement is that if the visitor fiddles with the URL, and there is no corresponding case, the default will be shown.

We want our visitors to see the form by default, so now we add it to our PHP snippet. To save us having to echo the data and then escape all of the quotation marks in the HTML, we can close PHP while we add our form, then re-open it:

<?php
switch ($_GET['page']) {
	case "process":
		// process form
	break;
	default:
		// show form
?>
		<form action="error.php?page=process" method="post"><p>
		<label><input type="text" id="page" name="page" /> Page URL</label><br />
		<label><input type="text" id="error" name="error" /> Error</label><br />
		<label><input type="text" id="correction" name="correction" /> Correction</label><br />
		<input type="submit" name="submit" id="submit" value="Send" />
		</p></form>
<?php
	break;
} ?>

The next part involves processing our input. First, we want to make sure the data being sent is appropriate for the form. To do this we shall strip out tags, change entities like & to their HTML equivalent and check for meta injection to prevent spam e-mails being sent. This makes our form nice and secure (code is commented so you can see what’s happening):

// create a function to clean our data: it strips tags, converts entities and trims whitespace
function clean($data) {
	$data = trim(htmlentities(strip_tags($data)));
	return $data;
}
//create a string of exploits and injections to check against later - the /i makes the contents inbetween non case-sensitive
$exploits = "/(content-type|bcc:|cc:|document.cookie|onclick|onload)/i";

// loop through the submitted data, cleaning it with our function
foreach ($_POST as $key => $val) {
	$clean[$key] = clean($val);

	// check to make sure there are no empty fields
	if (empty($val)) {
		exit("<p>All fields are required!</p>");
	}

	// check our data against the exploits above and exit if found
	if (preg_match($exploits, $val)) {
		exit("<p>No naughty exploits please!</p>");
	}
}

We now have clean data, in (wait for it..) a $clean[] array! This will be $clean['page'], $clean['error'] and $clean['correction'] — where each array key corresponds to the name of the field from the HTML form.

The next part is doing something with the data. In this instance, we want it e-mailed to the site owner so they can fix the mistakes. Let’s compose our mail:

$recipient = "you@your-site.com"; // this is your email, don't forget to change it!
$subject = "Error Submission";
$message = "Page: {$clean['page']} \n";
$message .= "Error: {$clean['error']} \n";
$message .= "Correction: {$clean['correction']}";
$headers = "From: Your Website <you@your-site.com>"; // this is your site/email, don't forget to change this too!

// now we send the message, or give an error if it can't be sent
if (mail($recipient,$subject,$message,$headers)) {
	echo "<p>The error was sent, thanks!</p>";
} else {
	echo "<p>The error could not be sent at this time, sorry.</p>";
}

All of these bits of code now have to go together — our form, our security checks and processing, and then the mailing of the details:

<?php
error_reporting(0);
switch ($_GET['page']) {
	case "process":
		// process form

		// create a function to clean our data: it strips tags, converts entities and trims whitespace
		function clean($data) {
			$data = trim(htmlentities(strip_tags($data)));
			return $data;
		}
		//create a string of exploits and injections to check against later - the / /i makes the contents inbetween non case-sensitive
		$exploits = "/(content-type|bcc:|cc:|document.cookie|onclick|onload)/i";

		// loop through the submitted data, cleaning it with our function
		foreach ($_POST as $key => $val) {
			$clean[$key] = clean($val);

			// check to make sure there are no empty fields
			if (empty($val)) {
				exit("<p>All fields are required!</p>");
			}

			// check our data against the exploits above and exit if found
			if (preg_match($exploits, $val)) {
				exit("<p>No naughty exploits please!</p>");
			}
		}

		$recipient = "you@your-site.com"; // this is your email, don't forget to change it!
		$subject = "Typing Error Submission";
		$message = "Page: {$clean['page']} \n";
		$message .= "Error: {$clean['error']} \n";
		$message .= "Correction: {$clean['correction']}";
		$headers = "From: Your Website <you@your-site.com>"; // this is your site/email, don't forget to change this too!

		// now we send the message, or give an error if it can't be sent
		if (mail($recipient,$subject,$message,$headers)) {
			echo "<p>The error was sent, thanks!</p>";
		} else {
			echo "<p>The error could not be sent at this time, sorry.</p>";
		}
	break;
	default:
		// show form
?>
		<form action="error.php?page=process" method="post"><p>
		<label><input type="text" id="page" name="page" /> Page URL</label><br />
		<label><input type="text" id="error" name="error" /> Error</label><br />
		<label><input type="text" id="correction" name="correction" /> Correction</label><br />
		<input type="submit" name="submit" id="submit" value="Send" />
		</p></form>
<?php
	break;
} ?>

Save that as error.php and link to it from your website — now your visitors can help find those annoying errors and you can get them fixed.

Speak Your Mind

*