Yet another awesome service from google. reCaptcha. More on that later. But firstly, sending from the right address.
Helping out a friend at her new(ish) job and their contact form simply sucked. Suppose it takes a bit of a background in both PHP web coding and more so in understanding Mail protocols than anything else.
The first thing people really need to get out of the habit is trying to send emails as the person who wishes to contact you. Take in this small example;
<?php $to = 'contact@mydomain.com'; $subject = 'Website Contact Form'; $message = $_POST['formMessage']; $headers = 'From: ' . $_POST['formEmailAddress'] . "\r\n"; mail($to, $subject, $message, $headers); ?>
Without getting hooked up on using raw entries from $_POST, basically the above code will take your contact details and attempt to send it to yourself. You write into the headers that this email is coming from whatever address the user entered when filling in the form.
THAT'S A BIG NO NO. More and more mail servers today (including your own, which is where some of the issue comes) checks the IP and/or domain name of where an email is being sent from, in this case it's your webserver, and looks up that domain to see if that domain or IP address is allowed to pretend to be sending mail. I promise no one has added in your domain details to allow to send email as them. Certainly not the bigger dogs like Bigpond, Optus etc.
This is just one method that checks mail servers use today to check the authenticity of mail getting into people's boxes. Otherwise you can basically be sending mail out as Google or even PayPal.
Here's what you should have done when coding your contact form.
<?php $to = 'contact@mydomain.com'; $subject = 'Website Contact Form'; $message = $_POST['formMessage']; $headers = 'From: contact@mydomain.com' . "\r\n" . 'Reply-To: ' . $_POST['formEmailAddress'] . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, $headers); ?>
So how's this work now? Basically, we're saying this email we're going to get is from our OWN domain. However when you hit the reply to start a conversation with the user that filled in the contact form, your email client will use the details in the Reply-To. Adding the X-Mailer section there is to let severs know that yes indeed this message has been sent from a PHP script.
Because your script is now sending from your website as your own email (typically where your mailserver resides) this solves some of the more common 550 errors in emails (Email error: 550 SPF: x.x.x.x is not allowed to send mail from ...)
Doing things properly you shouldn't stop there guys. The really good and neat way of sending mail out of your web scripts is to connect to your mail server directly, and send it from there. Need pear with it's mail modules installed for PHP.
If you don't already have this, you should lightly slap yourself and then quickly install it.
On Ubuntu:
sudo apt-get install php-pear sudo pear install mail sudo pear install Net_SMTP sudo pear install Auth_SASL sudo pear install mail_mime
Here's how our example would work now.
<?php include "Mail.php"; $to = 'contact@mydomain.com'; $headers['From'] = 'webmaster@mydomain.com'; $headers['To'] = $to; $headers['Subject'] = 'Website Contact Form'; $headers['Reply-To'] = $_POST['formName'] . '<' .$_POST['formEmailAddress'] . '>'; $smtpinfo['host'] = 'localhost'; $smtpinfo['port'] = '25'; $smtpinfo['auth'] = true; $smtpinfo['username'] = 'my_mail_username'; $smtpinfo['password'] = 'my_mail_password'; $mail_message = $_POST['formMessage']; $mail_handler =& Mail::factory("smtp", $smtpinfo); $mail_handler->send($to, $headers, $mail_message); ?>
Naturally I'd expect you to validate your data and not just use raw data sent from the browser, but this will connect up to a SMTP server and send it off via that server (which lets your messages get signed by a range of other anti-spam measures in place today).
If you require an SSL connection to your mail server (for example, google handles your mail for you (like it does for me)) you can change the host to "ssl://hostname" and the Mail package will work it out from there. Sadly it's not shown on the documentation about that handy little trick on the Pear page.
Another alternative is using sockets directly, which is fantastic and awesomes (and doesn't require Pear/Mail), and you can find a heap of PHP Libraries out there to give you access to do so. Personally I'm a bit of a fan of CodeIgniter and has these sorts of things built in already. Epic win.
GETTING SIDE TRACK HERE, but hopefully you'll start to use a neater way of sending your contact form messages out now.
Google reCaptcha adds that (sometimes) annoying little image to forms before you get to fill them in. Basically ensuring you're human and not some spam bot with insecurities about it's epen requiring extensions (CWOTIDIDTHAR?).
It's actually really to get set up and working on your site, for anything really - not just contact forms (although it works quickly there too). Basically you sign up for a Private and Public Key over at google and then download the quick library to use it.
After you've put it somewhere with your code files, you include the file, add some lines of code, and volia. How easy is that. See below;
<?php require_once('recaptchalib.php'); $privatekey = "your_private_key"; // Change this to your Private Key $publickey = "your_public_key"; // Change this to your Public Key if (isset($_POST['login'])) { // Do some validation stuffs here! // Check the Captcha $resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if (!$resp->is_valid) { // reCaptcha failed. Do stuffs } else { // reCaptcha all good. Do whatever else } } ?><html> <head></head> <body> <form method="POST" action="<?=$_SERVER['PHP_SELF'];?>"> <input type="text" name="username" /> <br /> <input type="password" name="password" /> <br /> <?=recaptcha_get_html($publickey);?> <input type="submit" name="login" /> </form> </body> </html>
You can change the "look" or theme of reCaptcha by adding a small snippet of javascript before the element appears;
<script type="text/javascript"> var RecaptchaOptions = { theme : 'clean' }; </script>
The element appears in a div with the ID of "recaptcha_widget_div" so if you want to adjust margins or padding for that div it appears in (being as lazy as me and NOT wanting to have more container divs than I can poke a stick at) you can change that in your own CSS stylesheets.
And that's about it for the moment. Hope I killed loads of your time and you wish for it back. ^_^
oh god i hope you dont actually use that mailer script.
“Without getting hooked up on using raw entries from $_POST…….”
“Naturally I’d expect you to validate your data and not just use raw data sent from the browser……”
Tim, it makes me sad to think just how bad of a troll you really are. Either that or you simply can’t read. Of which I do apologise for Australia’s education system failing you =P
In other news, I’m starting to hate wordpress Syntax higherlighters and the grief they are causing me….. thinking I should write one up….
Also reCaptcha is _not_ dependant on Javascript. It does make it look a lot more sexy, but it’s fall back is on iframes. And while I hate frames in general, it does the job of talking to the google server without javascript.
I apologise for the syntax higherlighter. Seems to be hating me tonight. Trying another plugin for it doesn’t seem much better as it’s killed my tab formatting….