Lesson 8 - E-mail form in PHP
In the previous lesson, More on Conditions in PHP - Casting, composing, and switches, we finished up learning about conditions in PHP. In today's lesson, we're going to be making an e-mail form as promised. Anyone who visits our website will be able to enter a message and the form will send it to us via e-mail. It's a very useful widget for our website and helps our visitors contact us easily.
The HTML part
The application will be split up into 2 parts as always. In this case, both
parts will be in the same file - mailform.php
. Mainly because we
want to be able to access the form while processing its data. If the user fills
something in wrong, we'll print an error message above the form.
The HTML part will contain a form with the following fields:
- Name - The visitor's name (in order to know who's contacting us)
- E-mail address - The visitor's e-mail address (to be able to reply to him/her)
- Message - The message that the visitor entered
- Anti-spam filter - Spam protection
All of the above should be clear to you all, except for the anti-spam filter. Let's talk about spam before we move on.
Spam
When you upload a page that contains a form to the Internet, after some time, bots will appear send ads through the form. This is mainly due to the form needing to send data to an external source. If a bot inserts a URL into the form, mostly pornography, and loans, the visitors would be sent to the ad's URL.
We can defend against spam very effectively at this point in time. We use
Turing tests, commonly known as Captchas, to protect web forms from bots. The
whole point is to ask a question that could only be answered by a human being.
The first wave of captchas displayed images with a few letters and numbers on it
and took it for granted that spam bots couldn't read images. As time passed,
spammers developed substantially effective OCR readers that could read images
even better than humans do. What we will do is keep it simple and secure because
there is nothing easier than to ask a question that spam-bots can't answer.
"What's the current year?"
will do the trick for us.
Form
Now, let's go ahead and create a new project. The code for an HTML site with a form looks something like this:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Contact form</title> </head> <body> <p>You can contact me by using form below.</p> <form method="POST"> <table> <tr> <td>Your name</td> <td><input name="name" type="text" /></td> </tr> <tr> <td>Your e-mail</td> <td><input name="email" type="email" /></td> </tr> <tr> <td>Current year</td> <td><input name="abc" type="number" /></td> </tr> </table> <textarea name="message"></textarea><br /> <input type="submit" value="Send" /> </form> </body> </html>
The result:
I placed the form fields on a table so that it would be aligned properly.
Doing so is a common approach used to style a form quickly. As you may have
noticed, the form lacks an action parameter that submits the data in the same
.php\
file. The field for entering the current year is labeled
"abc"
to be more confusing for robots (feel free to choose your own
input name).
The PHP part
At the very beginning of the file, we'll add in the PHP directive so that we can get right to programming:
<?php ?>
Validation
Remember that every form absolutely must have some sort of validation. Validations check whether a form is filled in properly. We still haven't gone over what is necessary in order to check whether the entered values are correct, but you do know enough to check whether they're empty or not.
Other than empty fields, there is another problem we could easily run into - unsubmitted forms. We have to keep in mind that people might pull the form up and not submit it. Remember that we have both the processing and the rendering located in the same script, so the user is able to display the form and not submit it. Based on what you learned in the previous lesson, you know that when we write:
if ($_POST)
The condition would only be true if the array is not empty.
We should be also aware that the form could also have been left unsubmitted
entirely. We'll have to check whether all of the necessary variables are present
in the $_POST
array. For that, we use the isset()
function.
BEWARE! - Lots of beginners use the following code for form validation:
if ($_POST['name']) { // ... }
Doing so is totally wrong and if the form wasn't submitted PHP will print a
very nasty error since we'd be trying to read from a non-existing variable. The
same people who do this usually "solve" the error by turning off PHP error
reporting instead of fixing the code. You will later find them on forums asking
why they can't find mistakes in their code anymore. Save yourself the grief and
don't be like them
While on the topic of error reporting, your local server (your desktop
computer) has to have it turned ON and the production server (the one on the
Internet) has to have it OFF. This configuration allows you to find most errors
and prevent attackers from breaking your application thanks to visible error
messages. Error reporting can be turned on/off in php.ini
. However,
in some cases, you won't have access to it on the production server (for which
you will have to go through your web host administration panel to do the needed
changes).
Here is a more appropriate way of validating a form:
$notice = ""; if ($_POST) // There is something in _POST array and the form was submitted { if (isset($_POST['name']) && $_POST['name'] && isset($_POST['email']) && $_POST['email'] && isset($_POST['message']) && $_POST['message'] && isset($_POST['abc']) && $_POST['abc'] == date('Y')) { // Then we'll send the email... } else $notice = "The form was not filled properly"; }
The entire code is wrapped in a condition that checks whether anything was
sent to $_POST
at all. If nothing was submitted, it will not
process anything. The next condition checks whether each field has been
submitted and contains text. Here, we also check whether the entered year is the
current one. As you may have guessed, the $notice
variable is for
when the user in cases a validation wasn't successful. The notice is later
printed in the HTML part of the script.
Processing
Sending the e-mail itself is relatively straightforward. To do so, we use the
mb_send_mail()
function which supports UTF-8 encoding (which the
mail()
function does not). We'll talk about functions with the
"mb_"
prefix later. For now, all you need to know is that you will
most likely need to set-up an encoding at the very beginning of the file before
using them:
<?php mb_internal_encoding("UTF-8");
Now, let's move add content to the condition that validates the forn, send the e-mail, and set the $notice variable:
$header = 'From:' . $_POST['email']; $header .= "\nMIME-Version: 1.0\n"; $header .= "Content-Type: text/html; charset=\"utf-8\"\n"; $address = '[email protected]'; $subject = 'New e-mail form message'; $success = mb_send_mail($address, $subject, $_POST['message'], $header); if ($success) { $notice = 'E-mail was successfully sent, I will respond as soon as I can.'; } else $notice = 'E-mail was not sent, make sure you have entered your email address correctly.';
An email header requires several variables, an address to send the email to
(use your own) and a subject. Don't worry about the header. All it is is the
specifications that the email requires, nothing more to it. The main thing here
is the variable on the first line that holds the sender's address. The e-mail
will look like it was sent from that address even though it was sent by our code
from our website. The mb_send_mail()
function returns
true
when an e-mail was successfully sent and false
if
it wasn't. We store its value in the $success
variable and assign
the $notice
based on the result.
Modifying the form
Let's move back to our form. We'll insert another PHP directive right above
the <form>
tag. Here, we'll print the $notice
variable, after checking whether it is empty:
<?php if ($notice) echo('<p>' . $notice . '</p>'); ?>
Done! Your form is now able to send e-mails and display whether the action was successful or not. You might need to upload it to your web host in order for it to work. In XAMPP, the default e-mail sending settings will not work unless you set it up manually. If you have trouble setting it up, don't worry, just upload the script to a web host and try it online.
In the next lesson, Improving the e-mail form in PHP, we'll finish working on this form. If you feel like you got any part of today's lesson wrong, the code can be downloaded below.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 100x (1.17 kB)
Application includes source codes in language PHP