One common means of collecting form data is to email it to yourself. If you don’t get many form responses and don’t need to collect that data into a database, this is a quick and simple means of accepting form responses.
Email: Add a name
When you collect form data, it’s nice to have a name to attach to the data. In order to add a name, however, we need a Name object as well as a FavoriteColor object. The two objects will act nearly the same, so rename FavoriteColor to FormField. Add a “fieldName” parameter to the __construct method and use it in the error message. This is what it will now look like:
<?php
class FormField {
public $value = null;
public $fieldName;
protected $submitted = false;
public function __construct($fieldName) {
$this->fieldName = $fieldName;
$this->clean();
}
public function answered() {
if ($this->submitted) {
if ($this->value === '') {
echo "<p>You need to enter a {$this->fieldName}!</p>\n";
} else {
return true;
}
}
return false;
}
…
protected function clean() {
if (isset($_POST[$this->fieldName])) {
$this->submitted = true;
$value = $_POST[$this->fieldName];
$value = trim($value);
$value = strtolower($value);
$value = htmlentities($value);
$this->value = $value;
}
}
}
?>
Now would be a good time to change the .phpi filename to fields.phpi. The web page will need to be changed to:
include_once('/home/USERNAME/includes/fields.phpi');
$color = new FormField('color');
Test it. Then, we can add a new field to the form to collect their name:
include_once('/home/USERNAME/includes/fields.phpi');
$color = new FormField('color');
$name = new FormField('name');
…
<?php IF ($color->answered() && $name->answered()):?>
<p style="color: <?php echo $color->value; ?>; background-color: <?php echo $color->background(); ?>">
You said your favorite color was <?php echo $color->value; ?>.
Thanks, <?php echo $name->value; ?>!
</p>
<?php ENDIF; ?>
<p>
What is your favorite color?
<input type="text" name="color" value="<?php echo $color->value; ?>" />
</p>
<p>
What is your name?
<input type="text" name="name" value="<?php echo $name->value; ?>" />
</p>
<input type="submit" />
Form respondents will need to answer both the name and the color, and they will be named in the response.
However, take a good look at the FormField code. This generically-named class has a method in it specifically for dealing with colors. Further, if you look at the thanks, you’ll see the name in all lower case. We should remove the color code and the lower-case code, and create a ColorField class that inherits from FormField. Remove the background method from FormField, and remove the strtolower line from the clean method of FormField. Then, create ColorField to extend FormField with color-specific functionality:
class ColorField extends FormField {
public function background() {
if ($this->value == 'white') {
$color = 'green';
} else {
$color = 'white';
}
return $color;
}
protected function clean() {
parent::clean();
if (isset($this->value)) {
$this->value = strtolower($this->value);
}
}
}
There are two things going on here. First, because ColorField extends FormField, it has all of the functionality of FormField. We don’t have to duplicate the __construct or the answered or the clean. They’re inherited by ColorField (the child) from FormField (the parent). You’ll hear parent/child a lot when reading about classes.
We can add completely new methods, such as, in this case, the background method. It exists on ColorField but does not exist on FormField.
We can also intercept existing methods, as we do here with the clean method. We intercept it, then call clean on the parent, and then make the resulting value lower-case.
Change the $color line in the web page to:
$color = new ColorField('color');
And when you re-run the page, you’ll get your name in the correct case, but colors will still be all lowercase.
Single vs. double quotes
In the above code, we use double quotes rather than single quotes around the “you need to enter a fieldname” text. Double quotes in PHP allow you to easily insert variables into the text. PHP will replace the variable names with the variable value. In this case, it will replace “{$this->fieldName}” with the value of $this->fieldName. You can also put “\n” and “\t” inside of double quotes to display new lines and tabs.
Single quotes do not do this. Anything inside of single quotes will be displayed exactly. So you’ll often use single quotes when displaying something including a dollar sign or a backslash.
Notification
It’s easy enough to send an email from PHP. You’ve already got a section of your web page where you display a message if both the color and the name were answered, so inside that section add:
<?php
$recipient = 'youraddress@example.com';
$subject = 'Favorite color of ' . $name->value;
$message = $name->value . ' said their favorite color was ' . $color->value . '.';
mail($recipient, $subject, $message);
?>
If a visitor fills out your form with the name “John Beat” and the favorite color of “green”, you’ll receive an email with the subject “Favorite color of John Beat” and the message:
John Beat said their favorite color was green.
You can format the message however you want. The “.” will combine strings of text; in programmer lingo, it will “concatenate” strings. You can have multiple lines in the message either by making a very long list of concatenations, or by having multiple lines of “$message .=”. The “.=” notation will append the new text to the old. For example, you might want to include more information about your visitors:
$message = $name->value . ' said their favorite color was ' . $color->value . '.';
$message .= "\n\n";
$message .= "Browser: " . $_SERVER['HTTP_USER_AGENT'] . "\n";
$message .= "IP Address: " . $_SERVER['REMOTE_ADDR'] . "\n";
mail($recipient, $subject, $message);
You’ll end up with an email that looks like:
John Beat said their favorite color was chartreuse.
Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
IP Address: 192.168.42.3
$_SERVER, like $_POST and $_SESSION, contains information that the server is passing to your script from other places. HTTP_USER_AGENT comes from the browser. In this case, I was using Safari on Mac OS X 10.6.8. This isn’t reliable, because it comes straight from the browser, and the browser can lie.
REMOTE_ADDR comes from what the server sees as the visitor’s IP address. The IP address is usually reliable, since it is necessary for the connection between the browser and the server to work. However, IP addresses are neither unique nor static. IP addresses provide interesting information, sometimes, but you can’t rely on them staying the same for a visitor or not being shared between multiple visitors all using the same service provider.
No untrusted recipients
Just as you can’t trust the data sent from a form when you display it on your web page, never send an e-mail to an address collected on an unprotected form. Remember the color lesson: you can’t trust that the person on the other end is honest—or even that they’re a person. Don’t let your forms become spam sources.
This is extremely important. Never use email addresses from forms as the recipients in your PHP-generated messages. Eventually, spammers or harassers will find your form and use it to spam and/or harass other people.